标签:
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4604 Accepted Submission(s): 1581
1 /* 2 把询问的几个区间先存起来,将其按照区间右端点从小到大排序,这样当去掉某一区间内的重复值时就不会 3 影响其他区间,因为其他区间的右端点要么比他小,要么比他大,比他小的不会受影响(树状数组向上更新) 4 ,比他大的恰好也要去重。去重时利用map。 5 */ 6 #include<iostream> 7 #include<cstdio> 8 #include<map> 9 #include<cstring> 10 #include<algorithm> 11 #include<cmath> 12 const int MAXN=50005; 13 const int MAXM=200005;//MAXM,MAXN改为30005,1000005就是HDU3333题题解 14 long long A[MAXN]; 15 long long NE[MAXN]; 16 int t,n,m; 17 struct Necklace 18 { 19 int R,L,id;//区间右端点,区间左端点,序号 20 }neck[MAXM]; 21 bool cmp(Necklace a,Necklace b) 22 { 23 if(a.R==b.R) 24 return a.L<b.L; 25 else return a.R<b.R; 26 } 27 int lowbit(int x) 28 { 29 return x&(-x); 30 } 31 void add(int id,long long c) 32 { 33 while(id<=MAXN) 34 { 35 A[id]+=c; 36 id+=lowbit(id); 37 } 38 } 39 long long sum(int id) 40 { 41 long long s=0; 42 while(id>0) 43 { 44 s+=A[id]; 45 id-=lowbit(id); 46 } 47 return s; 48 } 49 using namespace std; 50 int main() 51 { 52 scanf("%d",&t); 53 while(t--) 54 { 55 scanf("%d",&n); 56 for(int i=1;i<=n;i++) 57 scanf("%lld",&NE[i]); 58 scanf("%d",&m); 59 for(int i=0;i<m;i++) 60 { 61 scanf("%d%d",&neck[i].L,&neck[i].R); 62 // if(neck[i].L>neck[i].R) 63 // swap(neck[i].L,neck[i].R); 64 neck[i].id=i; 65 } 66 sort(neck,neck+m,cmp); 67 int p=1; 68 map<int,int>mp; 69 long long ans[MAXM]; 70 memset(A,0,sizeof(A)); 71 for(int i=0;i<m;i++) 72 { 73 while(p<=neck[i].R)//小于等于区间右端点的 74 { 75 long long x=NE[p]; 76 if(mp[x]!=0)//如果前面出现过此X值就减去旧的加上新的 77 add(mp[x],-x); 78 add(p,x); 79 mp[x]=p; 80 p++; 81 } 82 ans[neck[i].id]=sum(neck[i].R)-sum(neck[i].L-1); 83 } 84 for(int i=0;i<m;i++) 85 printf("%lld\n",ans[i]); 86 } 87 return 0; 88 }
HDU3874 /HDU3333 树状数组 区间求不重复数和
标签:
原文地址:http://www.cnblogs.com/--ZHIYUAN/p/5914030.html