洛谷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 }

猜你喜欢

转载自www.cnblogs.com/MediocreKonjac/p/9118561.html
今日推荐