解题:CQOI 2017 老C的任务

题面

找到真正的KD-Tree题目了!然而出题人并不打算放KD-Tree过,只能O2了

  1 // luogu-judger-enable-o2
  2 #include<cstdio>
  3 #include<cctype>
  4 #include<cstring>
  5 #include<algorithm>
  6 using namespace std;
  7 const int N=100005;
  8 int cmp;
  9 struct a
 10 {
 11     int pos[2],val;
 12 }mem[N],kdt[N];
 13 bool operator < (a x,a y)
 14 {
 15     return x.pos[cmp]<y.pos[cmp];
 16 }
 17 struct b
 18 {
 19     int mn[2],mx[2];
 20 }qry;
 21 int son[N][2],mini[N][2],maxx[N][2];
 22 long long sum[N],ans;
 23 int n,m,f,t1,t2,cnt;
 24 void read(int &x)
 25 {
 26     x=f=0; char ch=getchar();
 27     while(!isdigit(ch))
 28         f|=ch=='-',ch=getchar();
 29     while(isdigit(ch))
 30         x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
 31     x=f?-x:x;
 32 }
 33 void write(long long x)
 34 {
 35     if(x>9) write(x/10);
 36     putchar(x%10|48);
 37 }
 38 bool Outof(int nde)
 39 {
 40     for(int i=0;i<=1;i++)
 41         if(qry.mn[i]>maxx[nde][i]||qry.mx[i]<mini[nde][i])
 42             return true; return false;
 43 }
 44 bool Allin(int nde)
 45 {
 46     for(int i=0;i<=1;i++)
 47         if(qry.mn[i]>mini[nde][i]||qry.mx[i]<maxx[nde][i])
 48             return false; return true;
 49 }
 50 bool Partin(a nde)
 51 {
 52     for(int i=0;i<=1;i++)
 53         if(qry.mn[i]>nde.pos[i]||qry.mx[i]<nde.pos[i]) 
 54             return false; return true;
 55 }
 56 void Pushup(int nde)
 57 {
 58     int lson=son[nde][0],rson=son[nde][1];
 59     sum[nde]=sum[nde]+sum[lson]+sum[rson];
 60     for(int i=0;i<=1;i++)
 61         if(son[nde][i])
 62         {
 63             int sn=son[nde][i];
 64             for(int j=0;j<=1;j++)
 65             {
 66                 mini[nde][j]=min(mini[nde][j],mini[sn][j]);
 67                 maxx[nde][j]=max(maxx[nde][j],maxx[sn][j]);
 68             }
 69         }
 70 }
 71 void Create(int nde,int l,int r,int typ)
 72 {
 73     int mid=(l+r)/2;
 74     cmp=typ,nth_element(mem+l,mem+mid,mem+r+1);
 75     kdt[nde]=mem[mid],sum[nde]=mem[mid].val;
 76     for(int i=0;i<=1;i++) 
 77         mini[nde][i]=maxx[nde][i]=mem[mid].pos[i];
 78     if(l<mid) Create(son[nde][0]=++cnt,l,mid-1,typ^1);
 79     if(r>mid) Create(son[nde][1]=++cnt,mid+1,r,typ^1);
 80     Pushup(nde);
 81 }
 82 void Query(int nde)
 83 {
 84     if(Outof(nde)) return ;
 85     if(Allin(nde)) {ans+=sum[nde]; return;}
 86     if(Partin(kdt[nde])) ans+=kdt[nde].val;
 87     Query(son[nde][0]),Query(son[nde][1]);
 88 }
 89 int main()
 90 {
 91     register int i;
 92     read(n),read(m);
 93     for(i=1;i<=n;i++)
 94         read(mem[i].pos[0]),read(mem[i].pos[1]),read(mem[i].val);
 95     cnt=1,Create(1,1,n,0);
 96     for(i=1;i<=m;i++)
 97     {
 98         read(qry.mn[0]),read(qry.mn[1]);
 99         read(qry.mx[0]),read(qry.mx[1]);
100         ans=0,Query(1),write(ans),puts("");
101     }
102     return 0;
103 }
View Code
原文地址:https://www.cnblogs.com/ydnhaha/p/10181156.html