【ContestHunter】【弱省胡策】【Round0】(A)&【Round1】(B)

DP+容斥原理or补集转化?/KD-Tree


  唔……突然发现最早打的两场(打的最烂的两场)没有写记录……(太烂所以不忍记录了吗。。。

  还是把搞出来了的两道题记录一下吧= =勉强算弥补一下缺憾……

Round0 A

  要求问(1,2)->(n-1,m)  &  (2,1)->(n,m-1)的不相交路径条数,蒟蒻当时只想到了$N^3$的DP……即枚举当前的总步数,以及两个人分别横向走了几步。

  其实正解是(也只能是?)$O(N^2)$的!

  ans=calc{(1,2)->(n-1,m)}*calc{(2,1)->(n,m-1)} - calc{(1,2)->(n,m-1)}*calc{(2,1)->(n-1,m)}

  后面减去的那是啥呢?是两个人走到对方的目的地的总方案数……也就是两人路径交叉的方案数!将交叉的后半段交换一下,与两人走到各自的目的地,且路径发生交叉的方案一一对应!

  (还是容斥原理?)

  我比较傻逼,边界情况没有处理全2333……比如(n-1,m)和(n,m-1)走不到啊什么的……

 1 //Round0 A
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<iostream>
 7 #include<algorithm>
 8 #define rep(i,n) for(int i=0;i<n;++i)
 9 #define F(i,j,n) for(int i=j;i<=n;++i)
10 #define D(i,j,n) for(int i=j;i>=n;--i)
11 using namespace std;
12 typedef long long LL;
13 inline int getint(){
14     int r=1,v=0; char ch=getchar();
15     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
16     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
17     return r*v;
18 }
19 const int N=2010,mod=1e9+7;
20 /*******************template********************/
21 int n,m,a[N][N];
22 int f[N][N];
23 char s[N];
24 
25 LL calc(int x1,int y1,int x2,int y2){
26     memset(f,0,sizeof f);
27     f[x1][y1]=1;
28     F(i,x1,x2) F(j,y1,y2){
29         if (a[i-1][j]) (f[i][j]+=f[i-1][j])%=mod;
30         if (a[i][j-1]) (f[i][j]+=f[i][j-1])%=mod;
31     }
32     return f[x2][y2];
33 }
34 int main(){
35 #ifndef ONLINE_JUDGE
36     freopen("A.in","r",stdin);
37     freopen("A.out","w",stdout);
38 #endif 
39     n=getint(); m=getint();
40 
41     F(i,1,n){
42         scanf("%s",s+1);
43         F(j,1,m) a[i][j]=s[j]=='0';
44     }
45 //    printf("%lld %lld %lld %lld\n",calc(1,2,n-1,m),calc(2,1,n,m-1),calc(1,2,n,m-1),calc(2,1,n-1,m));
46     if (a[1][2] && a[2][1] && a[n-1][m] && a[n][m-1])
47         printf("%lld\n",(calc(1,2,n-1,m)*calc(2,1,n,m-1)%mod-calc(1,2,n,m-1)*calc(2,1,n-1,m)%mod+mod)%mod);
48     else puts("0");
49     return 0;
50 }
View Code

Round1 B

  题意是求四维空间中的偏序最长链?。。。

  点数不多,排序以后暴力枚举每个点,求出在它之前出现的满足条件的点中,最大的DP值。

  

  记得做这场胡策的时候我刚学了KD-Tree = =

  然而我爆零了……

  为什么呢?不是估价了嘛……我把小于号写成大于号了……也就是说,我把可能成为ans的全部避!过!去!了!

  标算是搞完一个点以后进行修改,然而蒟蒻没有yy出来怎么修改……窝的做法是每算完一个点就把它插进去,然后重构啊之类的搞搞……(真是机(sha)智(bi)

  1 //Round 1 B
  2 #include<vector>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<iostream>
  7 #include<algorithm>
  8 #define rep(i,n) for(int i=0;i<n;++i)
  9 #define F(i,j,n) for(int i=j;i<=n;++i)
 10 #define D(i,j,n) for(int i=j;i>=n;--i)
 11 using namespace std;
 12 typedef long long LL;
 13 inline int getint(){
 14     int r=1,v=0; char ch=getchar();
 15     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
 16     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
 17     return r*v;
 18 }
 19 const int N=1e5+10,INF=1e9;
 20 /*******************template********************/
 21 
 22 int n,m,p[N],D,root;
 23 struct node{
 24     int d[4],mx[4],mn[4],l,r,D,size,v,maxv;
 25     int& operator [] (int x){return d[x];}
 26     void read(){F(i,0,3) d[i]=getint();}
 27 }t[N],t2[N],tmp;
 28 
 29 bool cmp(int x,int y){return t[x][D]<t[y][D];}
 30 bool operator < (node a,node b){
 31     F(i,0,3){
 32         if (a[i]<b[i]) return 1;
 33         if (a[i]>b[i]) return 0;
 34     }
 35     return 0;
 36 }
 37 #define L t[o].l
 38 #define R t[o].r
 39 #define mid (l+r>>1)
 40 
 41 void Push_up(int o){
 42     F(i,0,3){
 43         t[o].mn[i]=min(t[o][i],min(t[L].mn[i],t[R].mn[i]));
 44         t[o].mx[i]=max(t[o][i],max(t[L].mx[i],t[R].mx[i]));
 45     }
 46     t[o].maxv=max(t[o].v,max(t[L].maxv,t[R].maxv));
 47     t[o].size=t[L].size+t[R].size+1;
 48 }
 49 int build(int l,int r,int dir){
 50     D=dir;
 51     nth_element(p+l,p+mid,p+r+1,cmp);
 52     int o=p[mid];
 53     t[o].D=dir;
 54     L = l < mid ? build(l,mid-1,(dir+1)%4) : 0;
 55     R = r > mid ? build(mid+1,r,(dir+1)%4) : 0;
 56     Push_up(o);
 57     return o;
 58 }
 59 
 60 int cnt;
 61 void dfs(int o){
 62     if (!o) return;
 63     p[++cnt]=o;
 64     dfs(L); dfs(R);
 65 }
 66 void rebuild(int &o){
 67     cnt=0;
 68     dfs(o);
 69     o=build(1,cnt,t[o].D);
 70 }
 71 
 72 void Insert(int &o,int dir){
 73     if (!o){
 74         o=++m; t[o].D=dir;
 75         t[o]=tmp;
 76         F(i,0,3) t[o].mn[i]=t[o].mx[i]=t[o][i];
 77         t[o].maxv=t[o].v; t[o].size=1;
 78         return;
 79     }
 80     if (t[o][dir]<tmp[dir]){
 81         Insert(L,(dir+1)%4);
 82         Push_up(o);
 83         if (t[L].size>t[o].size*0.7) rebuild(o);
 84     }else{
 85         Insert(R,(dir+1)%4);
 86         Push_up(o);
 87         if (t[R].size>t[o].size*0.7) rebuild(o);
 88     }
 89 }
 90 
 91 int check(int o){
 92     if (!o) return 0;
 93     int ans=0;
 94     F(i,0,3) if(t[o].mx[i]<=tmp[i]) ans++;
 95     if (ans==4) return ans;
 96     ans=1;
 97     F(i,0,3) if (t[o].mn[i]>tmp[i]) ans=0;
 98     return ans;
 99 }
100 int dis(node a,node b){
101     F(i,0,3) if (a[i]>b[i]) return 0;
102     return a.v;
103 }
104 int ans;
105 void query(int o){
106     ans=max(dis(t[o],tmp),ans);
107     int dl=check(L),dr=check(R);
108     if (dl==4) ans=max(ans,t[L].maxv);
109     else if (dl && ans<t[L].maxv) query(L);
110     if (dr==4) ans=max(ans,t[R].maxv);
111     else if (dr && ans<t[R].maxv) query(R);
112 }
113 
114 int main(){
115 #ifndef ONLINE_JUDGE
116     freopen("B.in","r",stdin);
117     freopen("B.out","w",stdout);
118 #endif 
119     F(i,0,3) t[0].mn[i]=INF,t[0].mx[i]=-INF;
120     t[0].maxv=-INF;
121 
122     n=getint();
123     F(i,1,n) t2[i].read(),t2[i].v=1;
124     sort(t2+1,t2+n+1);
125 /*    t[m=1]=t2[1]; t[1].v=1;
126     F(i,2,n){
127         F(j,0,3) if (t2[i][j]!=t2[i-1][j]){ t[++m]=t2[i]; break;}
128         t[m].v++;
129     }
130     F(i,1,m) t2[i]=t[i];
131     n=m; m=0;
132 */    int anss=0;
133     F(i,1,n){
134         ans=0;
135         tmp=t2[i];
136         query(root);
137         t2[i].v+=ans;
138 //        printf("%d ",t2[i].v);
139         tmp=t2[i];
140         anss=max(anss,t2[i].v);
141         Insert(root,0);
142     }
143 //    puts("");
144     printf("%d\n",anss);
145     return 0;
146 }
View Code

 

posted @ 2015-06-16 15:51  Tunix  阅读(434)  评论(0编辑  收藏  举报