BZOJ 2120 数颜色
2120: 数颜色
Time Limit: 6 Sec Memory Limit: 259 MBSubmit: 8918 Solved: 3683
[Submit][Status][Discuss]
Description
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令: 1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。为了满足墨墨的要求,你知道你需要干什么了吗?
Input
第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。
Output
对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。
Sample Input
6 5
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6
Sample Output
4
4
3
4
4
3
4
HINT
对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。
2016.3.2新加数据两组by Nano_Ape
Source
一样的代码,在bzoj就过了,在洛谷就超时QAQ
#include <bits/stdc++.h> using namespace std; #define ll long long const int maxn=1e6+7; struct pap { int l; int r; int pre; int id; } node[maxn]; struct papp { int l; int r; } node1[maxn]; int ma,l,r,n,m,now; int x1,x2; char s[5]; ll ans; int a[maxn],b[maxn],c[maxn],num[maxn]; ll str[maxn]; bool cmp(pap x,pap y) { if(x.l/ma!=y.l/ma) { return x.l<y.l; } return x.r<y.r; } void update(int n,int k) { if(k==1) { if(++num[a[n]]==1) { ans++; } } else { if(--num[a[n]]==0) { ans--; } } } void pan(int now,int i) { if(node1[now].l>=node[i].l&&node1[now].l<=node[i].r) { if(--num[a[node1[now].l]]==0) { ans--; } if(++num[node1[now].r]==1) { ans++; } } swap(node1[now].r,a[node1[now].l]); } void solve() { memset(num,0,sizeof(num)); l=1; r=0; now=0; for(int i=1; i<=x1; i++) { while(r<node[i].r) { update(++r,1); } while(r>node[i].r) { update(r--,-1); } while(l>node[i].l) { update(--l,1); } while(l<node[i].l) { update(l++,-1); } while(now<node[i].pre) { pan(++now,i); } while(now>node[i].pre) { pan(now--,i); } str[node[i].id]=ans; } } int main() { while(~scanf("%d%d",&n,&m)) { ma=sqrt(n); ans=0,x1=0,x2=0; for(int i=1; i<=n; i++) { scanf("%d",&a[i]); } for(int i=1; i<=m; i++) { scanf("%s",s); if(s[0]=='Q') { x1++; scanf("%d%d",&node[x1].l,&node[x1].r); node[x1].pre=x2; node[x1].id=x1; } else if(s[0]=='R') { x2++; scanf("%d%d",&node1[x2].l,&node1[x2].r); } } sort(node+1,node+x1+1,cmp); solve(); for(int i=1; i<=x1; i++) { printf("%lld\n",str[i]); } } }