cdoj1342郭大侠与甲铁城
地址:http://acm.uestc.edu.cn/#/problem/show/1342
题目:
郭大侠与甲铁城
Time Limit: 1500/800MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
全世界被产业革命的波澜推动,自近世变迁至近代之时,不死的怪物突然出现。被钢铁的皮膜包覆,只要心脏不被破坏就不会消灭,被它啃咬的人似乎也会在死过一次之后复生,并开始袭击人类。之后被称为卡巴内的这些怪物爆发性地增殖,并覆盖了全世界。
远东岛国日本的人们,为了对抗卡巴内的威胁而在各地建造名为“驿”的城寨,并困守在其中,想方设法残存下去。能够在驿之间来往的只有装甲蒸汽机车(通称骏城),驿之间通过各自生产物的融通,总算是保证了生活。
住在以炼铁和蒸汽机的生产为业的显金驿的蒸汽锻冶少年,郭大侠。他为了打倒卡巴内,开发出独自的武器“贯筒”,同时期盼着有朝一日能够发挥出自己的力量。
某天,穿越前线的骏城之一甲铁城来到了显金驿。为了车辆的清扫整备而被召唤的郭大侠,目击到了从义务性的卡巴内检阅中被免除的不可思议少女。
当晚,郭大侠与自称为无名的那位白天的少女再会,此时骏城突然暴走并突入了显金驿。乘务员全灭,而且全部变成了卡巴内!
卡巴内从显金驿中溢出。如同要从被恐慌袭击的人浪中逆行一般,郭大侠奔跑着。这一次不能逃避,我要用贯筒打倒卡巴内!
——于是,为了成为真正能闪耀光辉的男人,郭大侠的战斗开始了。
……
现在在这个城市中有n个卡巴内,每个卡巴内都有他自身的属性a[i],郭大侠的贯筒能够一次性击穿[L,R]区间中拥有不同属性的怪物!
为了足够强的发挥自己的武器的实力,郭大侠必须提前知道自己的一次性贯筒能够击杀多少只怪物。
现在开始计算吧!
Input
第一行给你n,q,表示有n个卡巴内,q次询问
第二行有n个整数,表示每一个卡巴内的属性a[i]
接下来q行,每行两个整数Li,Ri,表示询问。
1<=n,q<=1000001<=n,q<=100000
1<=Li<=Ri<=n1<=Li<=Ri<=n
1<=a[i]<=100001<=a[i]<=10000
Output
对于每一个询问,输出答案!
Sample input and output
Sample Input | Sample Output |
---|---|
5 3 1 2 3 1 1 1 3 1 4 3 5 |
3 3 2 |
思路:
Ps:所有题目中搞了最久的题目。。。看了一天多,网上各种找资料。。智商-100
这题就是求区间内的不同数字的个数。
用树状数组做的,用线段树也可以就是了。用莫队也可以,不过我没搞出来,wa了几发、、
首先对所有询问按右区间排个序,然后对所有的询问从左向右扫一遍。。。。
对于每个属性都记录它上一次出现的位置,初始时默认为0,如果是第一次出现就把他加进树状数组(就是值+1),不是的话就把他从树状数组中删掉(值-1)
对于每个询问ans=sum(r)-sum(l-1),就这样把所有询问扫一遍就好了
写完后发现lowbit居然后为0,,,然后就tle了,,不过把所有数向右移下就好了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cmath> 5 #include <cstring> 6 #include <queue> 7 #include <stack> 8 #include <map> 9 #include <set> 10 #include <vector> 11 #include <cstdlib> 12 #include <string> 13 #include <bitset> 14 15 #define PI acos((double)-1) 16 #define E exp(double(1)) 17 #define K 100000 18 using namespace std; 19 struct node 20 { 21 int l,r,id; 22 }q[K]; 23 int c[K],a[10009],ans[K+10],last[K+10]; 24 int n; 25 bool cmp(node tx,node ty) 26 { 27 if(tx.r==ty.r) 28 return tx.l<ty.l; 29 return tx.r<ty.r; 30 } 31 void add(int x,int v) 32 { 33 while(x<=n) 34 { 35 c[x]+=v; 36 x+=x&(-x); 37 } 38 } 39 int sum(int x) 40 { 41 int ret=0; 42 while(x>0) 43 { 44 ret+=c[x]; 45 x-=x&(-x); 46 } 47 return ret; 48 } 49 int main(void) 50 { 51 int m,t=0; 52 cin>>n>>m; 53 memset(q,0,sizeof(q)); 54 memset(last,0,sizeof(last)); 55 memset(a,0,sizeof(a)); 56 for(int i=1;i<=n;i++) 57 { 58 scanf("%d",&t); 59 last[i]=a[t]; 60 a[t]=i; 61 } 62 for(int i=0;i<m;i++) 63 scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i; 64 sort(q,q+m,cmp); 65 memset(c,0,sizeof(c)); 66 t=0; 67 for(int i=0;i<m;i++) 68 { 69 while(t<q[i].r) 70 t++,add(last[t]+1,1),add(t+1,-1); 71 ans[q[i].id]=sum(q[i].l); 72 } 73 for(int i=0;i<m;i++) 74 printf("%d\n",ans[i]); 75 return 0; 76 }
作者:weeping
出处:www.cnblogs.com/weeping/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。