10.22T2 DSU算法

6029 -- 【2020级互测D8T2】长门有希的记录

 

Description

“——你今天很闲吧”
“啥…”
“两点整全员在车站前集合”
“喂…”
……
——漫无止境的八月
长门有希,作为对有机生命体接触用人型界面,有着各种各样既不科学也不魔法的能力。简单来讲,就是能够像游戏设计者更改游戏资料一样改变现实世界的物体与现象。(据说战斗时所使用的咒语是倒着读的SQL语句233)
在凉宫春日的强烈愿望之下,原本平淡的一个高一暑假变成了漫无止境的八月,作为唯一一个能够在时间的轮回中保持记忆的人型界面,15498次不断轮回带来的是错误与沉重压力的不断积累,有希需要做一些事情来放松自己。
在这段时间中,无聊至极的有希开始记录每一次轮回所做的事情。包括打棒球、烟花大会、钓鱼、墓地试胆、电影首映、海水浴、保龄球、卡拉OK等等(真是丰富啊) 。
现在,有希把这些事情按照发生的顺序抽象为了一个长度为 的序列,把每一个事件用一个 之间的数代替。出于无聊,她开始统计连续的时间段中SOS团做的次数最多的事情。如果有多种事件的出现次数一样,那么取编号最小的一个。她认为这一定程度上能够表示凉宫大团长的喜爱偏好,也许能够得到脱离无尽八月的方法。
长门同学选取区间是有一定的规则的,这些规则能够更好的帮助她分析大家的喜好。即选中的连续时间段不会相交,只有包含和相离这两种可能性。

Input

输入文件共M+3行。
第一行一个整数T,表示当前数据的编号。注意,这不是解题必须的。
第二行行包括两个整数N,M 。
接下来一行 N个数ai ,表示在第 i个时间段SOS 团所做事情的种类。
接下来M行,每行两个数li,ri ,表示询问的时间段。

Output

输出文件共M行,每行一个数,表示第 次询问的时间段中做的次数最多的事情的编号。

Sample Input

1
5 3
1 2 2 1 1
1 5
1 2
3 3

Sample Output

1 1 2 根据题意,显然。(注意[1,2] 中1 和2 出现次数相同,输出 1).

Hint

样例输入2
1
15 8
1 2 3 2 4 4 5 12 9 2 2 2 2 2 15
1 5
2 4
3 3
6 14
10 13
6 9
11 11
15 15
样例输出2:
2
2
3
2
2
4
2
15
 
 
 
DSU算法可以搞一下,实质上还是一个轻重链划分
code:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<stack>
 4 #include<algorithm>
 5 #define N 2000005
 6 using namespace std;
 7 struct node {
 8     int u,v;
 9 } e[N];
10 struct T {
11     int x,y,id;
12 } q[N];
13 stack<T>p;
14 int rd[N],first[N],nxt[N],cnt;
15 int n,m;
16 void add(int u,int v) {
17     e[++cnt].u=u;
18     e[cnt].v=v;
19     rd[v]++;
20     nxt[cnt]=first[u];
21     first[u]=cnt;
22 }
23 bool cmp(const T&a,const T&b) {
24     if(a.x==b.x)return a.y>b.y;
25     return a.x<b.x;
26 }
27 void build() {
28     for(int i=1; i<=m; i++) {
29         int x=q[i].x,y=q[i].y;
30         while(!p.empty()&&x<=p.top().y) {
31             add(p.top().id,i);
32             p.pop();
33         }
34         p.push((T) {
35             x,y,i
36         });
37     }
38 }
39 int siz[N],hson[N],ans[N];
40 void dfs(int x) {
41     siz[x]=1,hson[x]=0;
42     for(int i=first[x]; i; i=nxt[i]) {
43         int v=e[i].v;
44         dfs(v);
45         siz[x]+=siz[v];
46         if(!hson[x]||siz[hson[x]]<siz[v])hson[x]=v;
47     }
48 }
49 int id,max0;
50 int num[N],a[N];
51 void clear(int v) {
52     max0=0,id=1<<30;
53     for(int i=q[v].x; i<=q[v].y; i++)num[a[i]]--;
54 }
55 void insert(int x) {
56     num[x]++;
57     if(num[x]>max0) {
58         max0=num[x];
59         id=x;
60     } else if(num[x]==max0)id=min(id,x);
61 }
62 void solve(int x) {
63     for(int i=first[x]; i; i=nxt[i]) {
64         int v=e[i].v;
65         if(v==hson[x])continue;
66         solve(v),clear(v);
67     }
68     if(hson[x]) {
69         solve(hson[x]);
70         for(int i=q[x].x; i<=q[hson[x]].x-1; i++)insert(a[i]);
71         for(int i=q[hson[x]].y+1; i<=q[x].y; i++)insert(a[i]);
72         ans[q[x].id]=id;
73     } else {
74         for(int i=q[x].x; i<=q[x].y; i++)insert(a[i]);
75         ans[q[x].id]=id;
76     }
77 }
78 int main() {
79     int ty;
80     cin>>ty;
81     cin>>n>>m;
82     for(int i=1; i<=n; i++)cin>>a[i];
83     for(int i=1; i<=m; i++) {
84         cin>>q[i].x>>q[i].y;
85         q[i].id=i;
86     }
87     sort(q+1,q+m+1,cmp);
88     build();
89     for(int i=1; i<=m; i++) {
90         if(rd[i])continue;
91         dfs(i);
92         solve(i);
93         clear(i);
94     }
95     for(int i=1; i<=m; i++)cout<<ans[i]<<"\n";
96     return 0;
97 }

over

posted @ 2018-10-22 20:48  saionjisekai  阅读(157)  评论(0编辑  收藏  举报