前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >P3709 大爷的字符串题(50分)

P3709 大爷的字符串题(50分)

作者头像
attack
发布2018-04-12 15:45:47
5860
发布2018-04-12 15:45:47
举报

题目背景

在那遥远的西南有一所学校

/*被和谐部分*/

然后去参加该省省选虐场

然后某蒟蒻不会做,所以也出了一个字符串题:

题目描述

给你一个字符串a,每次询问一段区间的贡献

贡献定义:

每次从这个区间中随机拿出一个字符x,然后把x从这个区间中删除,你要维护一个集合S

如果S为空,你rp减1

如果S中有一个元素不小于x,则你rp减1,清空S

之后将x插入S

由于你是大爷,平时做过的题考试都会考到,所以每次询问你搞完这段区间的字符之后最多还有多少rp?rp初始为0

询问之间不互相影响~

输入输出格式

输入格式:

第一行两个数n,m,表示字符串长度与询问次数

之后一行n个数,表示字符串

由于你是大爷,所以字符集1e9

之后m行每行两个数,表示询问的左右区间

输出格式:

m行,每行一个数表示答案

输入输出样例

输入样例#1:

代码语言:javascript
复制
3 3
3 3 3
3 3
3 3
3 3

输出样例#1:

代码语言:javascript
复制
-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分,也可以进队了

代码语言:javascript
复制
  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 }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-06-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目背景
  • 题目描述
  • 输入输出格式
  • 输入输出样例
  • 说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档