洛谷P3810陌上花开
人傻常数大
cdq分治模板题,想起来貌似不难,但细节很多啊
相同元素的花不合并会算错
弱菜的我按归并写了,然而不如直接排序来得快
洛谷90分,一个点TLE
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100010 4 #define K 200010 5 inline bool isitdigit(char c){return c<='9'&&c>='0';} 6 inline int lowbits(int x){return x&-x;} 7 inline int read() 8 { 9 register int s;register char c; 10 while(!isitdigit(c=getchar())); 11 for(s=c-'0';isitdigit(c=getchar());s=(s<<1)+(s<<3)+c-'0'); 12 return s; 13 } 14 int n,k,tot; 15 int num[K],sum[N]; 16 inline void add(int x,int v){for(register int i=x;i<=k;i+=lowbits(i)) num[i]+=v;} 17 inline int query(int x){register int s=0;for(register int i=x;i;i-=lowbits(i)) s+=num[i]; return s;} 18 inline void clear(int x){for(register int i=x;i<=k;i+=lowbits(i)) num[i]=0;} 19 struct Dot{int a,b,c,ans,times;}dot[N],d[N],ope[N]; 20 inline bool operator < (const Dot & one,const Dot & another) 21 { 22 return 23 one.a!=another.a? one.a<another.a: 24 (one.b!=another.b? one.b<another.b: 25 one.c<=another.c); 26 } 27 void cdq(int l,int r) 28 { 29 if(l>=r) return; 30 register int mid=(l+r)>>1; 31 cdq(l,mid);cdq(mid+1,r); 32 register int i=l,j=mid+1,t=l,cnt=0; 33 while(i<=mid&&j<=r) 34 if(dot[i].b<=dot[j].b) ope[++cnt]=d[t++]=dot[i],add(dot[i].c,dot[i].times+1),i++; 35 else d[t]=dot[j],d[t++].ans+=query(dot[j++].c); 36 while(i<=mid) ope[++cnt]=d[t++]=dot[i],add(dot[i].c,dot[i].times+1),i++; 37 while(j<=r) d[t]=dot[j],d[t++].ans+=query(dot[j++].c); 38 for(--t;t>=l;--t) dot[t]=d[t]; 39 for(;cnt>=1;--cnt) clear(ope[cnt].c); 40 } 41 int main() 42 { 43 n=read(),k=read(); 44 for(register int i=1;i<=n;++i) 45 d[i].a=read(),d[i].b=read(),d[i].c=read(); 46 sort(d+1,d+1+n); 47 dot[++tot]=d[1]; 48 for(register int i=2;i<=n;++i) 49 if(d[i].a==dot[tot].a&&d[i].b==dot[tot].b&&d[i].c==dot[tot].c) 50 ++dot[tot].times; 51 else dot[++tot]=d[i]; 52 cdq(1,tot); 53 for(register int i=1;i<=tot;++i) 54 for(register int j=0;j<=dot[i].times;++j) 55 ++sum[dot[i].ans+dot[i].times]; 56 for(register int i=0;i<n;++i) printf("%d\n",sum[i]); 57 return 0; 58 }