P3709 大爷的字符串题(50分)
题目背景
在那遥远的西南有一所学校
/*被和谐部分*/
然后去参加该省省选虐场
然后某蒟蒻不会做,所以也出了一个字符串题:
题目描述
给你一个字符串a,每次询问一段区间的贡献
贡献定义:
每次从这个区间中随机拿出一个字符x,然后把x从这个区间中删除,你要维护一个集合S
如果S为空,你rp减1
如果S中有一个元素不小于x,则你rp减1,清空S
之后将x插入S
由于你是大爷,平时做过的题考试都会考到,所以每次询问你搞完这段区间的字符之后最多还有多少rp?rp初始为0
询问之间不互相影响~
输入输出格式
输入格式:
第一行两个数n,m,表示字符串长度与询问次数
之后一行n个数,表示字符串
由于你是大爷,所以字符集1e9
之后m行每行两个数,表示询问的左右区间
输出格式:
m行,每行一个数表示答案
输入输出样例
输入样例#1:
3 3 3 3 3 3 3 3 3 3 3
输出样例#1:
-1 -1 -1
说明
前4个点1s,后面的点4s
对于10%的数据,是样例
对于另外10%的数据,n,m <= 100
对于另外10%的数据,n,m <= 1000
对于另外10%的数据,n,m <= 10000
对于另外10%的数据,n,m <= 100000
对于100%的数据,n,m <= 200000
保证数据向某省省选day1T2一样sb,大家尽情用暴力水过题吧!
没事,你只要在一个好学校,就算这题只能拿到10分,也可以进队了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<cstdlib> 6 #include<algorithm> 7 #include<vector> 8 #define hh 10 9 using namespace std; 10 const int MAXN=2000001; 11 void read(int & n) 12 { 13 char c='+';int x=0;bool flag=0; 14 while(c<'0'||c>'9') 15 {c=getchar();if(c=='-')flag=1;} 16 while(c>='0'&&c<='9') 17 {x=x*10+(c-48);c=getchar();} 18 flag==1?n=-x:n=x; 19 } 20 int n,m; 21 int pos[MAXN]; 22 int base; 23 int rp=0; 24 struct node 25 { 26 int l,r,id; 27 }q[MAXN]; 28 struct dr 29 { 30 int a,p; 31 }a[MAXN]; 32 int comp(const node & a,const node &b) 33 { 34 if(pos[a.l]==pos[b.l]) 35 return a.r<b.r; 36 else 37 return pos[a.l]<pos[b.l]; 38 } 39 int cop(const dr &a,const dr &b) 40 { 41 return (a.a<b.a)||(a.a==b.a&&a.p<b.p); 42 } 43 int happen[MAXN];// 记录i出现了多少次 44 int cnt[MAXN];// 记录出现次数为j的有多少 45 int out[MAXN]; 46 void dele(int p) 47 { 48 if(rp==happen[p]&&cnt[happen[p]+hh]==1) 49 rp--; 50 cnt[happen[p]+hh]--; 51 cnt[happen[p]+hh-1]++; 52 happen[p]--; 53 } 54 void add(int p) 55 { 56 if(rp==happen[p]) 57 rp++; 58 cnt[happen[p]+hh]--; 59 cnt[happen[p]+hh+1]++; 60 happen[p]++; 61 } 62 int ls[MAXN]; 63 void modui() 64 { 65 int ll=1,rr=0; 66 for(int i=1;i<=m;i++) 67 { 68 for(;ll<q[i].l;ll++) 69 dele(ls[ll]); 70 for(;ll>q[i].l;ll--) 71 add(ls[ll-1]); 72 for(;rr>q[i].r;rr--) 73 dele(ls[rr]); 74 for(;rr<q[i].r;rr++) 75 add(ls[rr+1]); 76 out[q[i].id]=-rp; 77 } 78 for(int i=1;i<=m;i++) 79 printf("%d\n",out[i]); 80 } 81 int main() 82 { 83 read(n);read(m); 84 base=sqrt(n); 85 for(int i=1;i<=n;i++) 86 read(a[i].a),a[i].p=i; 87 sort(a+1,a+n+1,cop); 88 int j; 89 for(int i=1,j=0;i<=n;i++) 90 { 91 if (i==1||a[i].a!=a[i-1].a) j++; 92 ls[a[i].p]=j; 93 } 94 //for(int i=1;i<=n;i++) 95 // pos[i]=(i-1)/base+1; 96 int sqt=0; 97 for ( sqt=1; sqt*sqt<=n; sqt++); 98 99 for (int i=1; i<=n; i++) pos[i]=i/sqt; 100 101 cnt[0]=j; 102 for(int i=1;i<=m;i++) 103 { 104 read(q[i].l); 105 read(q[i].r); 106 q[i].id=i; 107 } 108 sort(q+1,q+m+1,comp); 109 modui(); 110 return 0; 111 }
作者:自为风月马前卒
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。