CodeM2018复赛

A BPM136

对于两边取对数,然后将pi和pj除过去,就可以DP了

方程为f[i]=sum{f[j]}+1 if ln(a[j])/j < ln(a[i])/i

 1 /* ***********************************************
 2 Author        :BPM136
 3 Created Time  :2018/7/7 19:11:25
 4 File Name     :A.cpp
 5 ************************************************ */
 6  
 7 #include<iostream>
 8 #include<cstdio>
 9 #include<algorithm>
10 #include<cstdlib>
11 #include<cmath>
12 #include<cstring>
13 #include<vector>
14 using namespace std;
15  
16 const int N = 105;
17  
18 long long f[N];
19 int n;
20 int a[N];
21  
22 int main() {
23     long long ans=0;
24     cin>>n;
25     for(int i=1;i<=n;i++) cin>>a[i];
26     for(int i=1;i<=n;i++) {
27         f[i]=1;
28         for(int j=1;j<i;j++) if(log(a[j]*1.0)/j < log(a[i]*1.0)/i) f[i]+=f[j];
29         ans+=f[i];
30     }
31     cout<<ans<<endl;
32     return 0;
33 }
View Code

B BPM136

给定M条有向边,询问是否有环,输入假加密(因为答案一定前面都是1后面都是0)

因为是假加密,所以可以二分答案,dfs判定即可

  1 /* ***********************************************
  2 Author        :BPM136
  3 Created Time  :2018/7/7 19:36:40
  4 File Name     :B.cpp
  5 ************************************************ */
  6  
  7 #include<iostream>
  8 #include<cstdio>
  9 #include<algorithm>
 10 #include<cstdlib>
 11 #include<cmath>
 12 #include<cstring>
 13 #include<vector>
 14 using namespace std;
 15  
 16 const int N = 200005;
 17  
 18 struct edge {
 19     int y,next;
 20 }e[N<<1],_e[N<<1];
 21 int last[N],ne;
 22 int _last[N],_ne;
 23  
 24 struct node {
 25     int x,y;
 26 }a[N];
 27  
 28 int n,m;
 29  
 30 void add(int x,int y) {
 31     e[++ne].y=y; e[ne].next=last[x]; last[x]=ne;
 32     _e[++_ne].y=x; _e[_ne].next=_last[y]; _last[y]=_ne;
 33 }
 34  
 35 int lfcou=0;
 36 int sortrem[N];
 37 int sortcou;
 38  
 39 int vis1[N];
 40 int vis2[N];
 41  
 42 void dfs1(int x) {
 43     vis1[x]=1;
 44     for(int i=last[x];i!=0;i=e[i].next) if(vis1[e[i].y]==0) {
 45         dfs1(e[i].y);
 46     }
 47     sortrem[sortcou++]=x;
 48 }
 49  
 50 void dfs2(int x) {
 51     vis2[x]=1;
 52     for(int i=_last[x];i!=0;i=_e[i].next) if(!vis2[_e[i].y]) {
 53         dfs2(_e[i].y);
 54     }
 55 }
 56  
 57 int check(int LIM) {
 58     memset(last,0,sizeof(last));
 59     memset(_last,0,sizeof(_last));
 60     _ne=0;
 61     ne=0;
 62     int ans=0;
 63     for(int i=1;i<=LIM;i++) {
 64         int x=a[i].x;
 65         int y=a[i].y;
 66         x=x-1-ans; y=y-1-ans;
 67         x=(x+n)%n;
 68         y=(y+n)%n;
 69         if(x==0) x=n;
 70         if(y==0) y=n;
 71  
 72         ans=1;
 73         add(x,y);
 74     }
 75     memset(vis1,0,sizeof(vis1));
 76     memset(vis2,0,sizeof(vis2));
 77     memset(sortrem,0,sizeof(sortrem));
 78     lfcou=0;
 79     sortcou=0;
 80     for(int i=1;i<=n;i++) if(vis1[i]==0) {
 81         dfs1(i);
 82     }
 83     for(int i=sortcou-1;i>=0;i--) if(vis2[sortrem[i]]==0) {
 84         ++lfcou;
 85         dfs2(sortrem[i]);
 86     }
 87     if(lfcou==n) return 1;
 88     return 0;
 89 }
 90  
 91 int main() {
 92     scanf("%d%d",&n,&m);
 93     for(int i=1;i<=m;i++) {
 94         int x,y;
 95         scanf("%d%d",&x,&y);
 96         a[i].x=x;
 97         a[i].y=y;
 98     }
 99  
100     int l=1,r=m;
101     int ans=-1;
102     while(l<=r) {
103         int mid=(l+r)/2;
104         if(check(mid)) {
105             l=mid+1;
106             ans=mid;
107         } else r=mid-1;
108     }
109     for(int i=1;i<=ans;i++) puts("1");
110     for(int i=ans+1;i<=m;i++) puts("0");
111     return 0;
112 }
View Code

C BPM136

给了张无向图,一些边上面有0和1,另一些为-1,其中-1的边可以定为0或者1,要求这张图每一个环的异或和为0,问方案数

考虑先加入01边,如果合法,再慢慢加入-1边,加入-1边时,如果这条边在一个连通块内,那么权值直接定下来了,否则就有两种选法。

注意dfs判断合法的时候continue和return应该写哪个

  1 /* ***********************************************
  2 Author        :BPM136
  3 Created Time  :2018/7/7 21:34:50
  4 File Name     :C.cpp
  5 ************************************************ */
  6  
  7 #include<iostream>
  8 #include<cstdio>
  9 #include<algorithm>
 10 #include<cstdlib>
 11 #include<cmath>
 12 #include<cstring>
 13 #include<vector>
 14 using namespace std;
 15  
 16 const int N = 100005;
 17 const long long MOD = 998244353;
 18  
 19 struct edge {
 20     int x,y,z;
 21     int next;
 22 }e[N<<1],b[N<<1];
 23 int last[N],ne=0;
 24  
 25 int n,m;
 26  
 27 void add(int x,int y,int z) {
 28     e[++ne].y=y; e[ne].z=z; e[ne].next=last[x]; last[x]=ne;
 29 }
 30 void add2(int x,int y,int z) {
 31     add(x,y,z);
 32     add(y,x,z);
 33 }
 34  
 35 bool cmp_edge(edge a,edge b) {
 36     return a.z>b.z;
 37 }
 38  
 39 int xo[N];
 40 int vis[N];
 41 int flag=0;
 42 void dfs(int x,int pre) {
 43     vis[x]=1;
 44     for(int i=last[x];i!=0;i=e[i].next) if(e[i].y!=pre) {
 45         if(vis[e[i].y]) {
 46             if(xo[e[i].y]^xo[x]^e[i].z == 1) flag=1;
 47             continue;
 48         }
 49         xo[e[i].y]=xo[x]^e[i].z;
 50         dfs(e[i].y,x);
 51     }
 52 }
 53  
 54 int F_f[N];
 55 int F_find(int x) {
 56     if(F_f[x]==x) return x;
 57     return F_f[x]=F_find(F_f[x]);
 58 }
 59  
 60 int main() {
 61     scanf("%d%d",&n,&m);
 62     for(int i=1;i<=m;i++) {
 63         int x,y,z;
 64         scanf("%d%d%d",&x,&y,&z);
 65         b[i].x=x;
 66         b[i].y=y;
 67         b[i].z=z;
 68     }
 69     //sort(b+1,b+m+1,cmp_edge);
 70     for(int i=1;i<=n;i++) F_f[i]=i;
 71     for(int i=1;i<=m;i++) {
 72         if(b[i].z==-1) continue;
 73  
 74         int x=b[i].x;
 75         int y=b[i].y;
 76         int z=b[i].z;
 77         add2(x,y,z);
 78         int dx=F_find(x);
 79         int dy=F_find(y);
 80         if(dx!=dy) F_f[dx]=dy;
 81     }
 82     for(int i=1;i<=n;i++) if(vis[i]==0) {
 83         dfs(i,0);
 84     }
 85     if(flag==1) {
 86         puts("0");
 87         return 0;
 88     }
 89  
 90     long long ans=1;
 91     for(int i=1;i<=m;i++) if(b[i].z==-1) {
 92         int dx=F_find(b[i].x);
 93         int dy=F_find(b[i].y);
 94         if(dx!=dy) {
 95             ans=ans * 2 % MOD;
 96             F_f[dx]=dy;
 97         }
 98     }
 99     cout<<ans;
100     return 0;
101 }
View Code

D BPM136

因为b序列的下凸性很容易可知b一定取a的下凸壳,上下平移一下即可,答案一定在下凸壳和ai的最大差的一半处取到。

注意long long

 1 /* ***********************************************
 2 Author        :BPM136
 3 Created Time  :2018/7/14 12:03:17
 4 File Name     :D.cpp
 5 ************************************************ */
 6 
 7 #include<iostream>
 8 #include<cstdio>
 9 #include<algorithm>
10 #include<cstdlib>
11 #include<cmath>
12 #include<cstring>
13 #include<vector>
14 using namespace std;
15 
16 const int N = 1000005;
17 
18 struct point {
19     long long x,y;
20     point() {}
21     point(int _x,int _y) : x(_x),y(_y) {}
22     point operator-(const point &b) {
23         point ret;
24         ret.x=x-b.x;
25         ret.y=y-b.y;
26         return ret;
27     }
28 };
29 
30 int a[N];
31 int n;
32 int sta[N];
33 int m;
34 
35 long long cross(point a,point b) {
36     return a.x*b.y-a.y*b.x;
37 }
38 long long cross(point a,point b,point c) {
39     return cross(b-a,c-a);
40 }
41 long long cross(int x,int y,int z) {
42     return (long long)(y-x)*(a[z]-a[x])-(long long)(z-x)*(a[y]-a[x]);
43 }
44 
45 long long GCD(long long a,long long b) {
46     if(b==0) return a;
47     return GCD(b,a%b);
48 }
49 
50 void f_update(long long &fz,long long &fm,long long x,long long y) {
51     y<<=1;
52     long long gcd=GCD(x,y);
53     x/=gcd;
54     y/=gcd;
55     if(y*fz<x*fm) fz=x,fm=y;
56 }
57 
58 int main() {
59     scanf("%d",&n);
60     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
61     m=0;
62     for(int i=1;i<=n;i++) {
63         //while(m>=2 && cross( point(sta[m-1],a[ sta[m-1] ]) , point(sta[m],a[ sta[m] ]) , point(i,a[i]) )<=0 ) m--;
64         while(m>=2 && cross(sta[m-1],sta[m],i)<0) m--;
65         sta[++m]=i;
66     }
67     //cout<<"tubao : "<<m<<endl;
68     //for(int i=1;i<=m;i++) cout<<sta[i]<<' '; cout<<endl;
69     long long fz=0,fm=1;
70     for(int i=1,R=1;i<=n;i++) {
71         while(R<=m && sta[R]<i) R++;
72         if(sta[R]==i) continue;
73         long long tfz,tfm;
74         long long lenx=sta[R]-sta[R-1];
75         long long leny=a[sta[R]]-a[sta[R-1]];
76         long long deltax=i-sta[R-1];
77         long long deltay=a[i]-a[sta[R-1]];
78         tfz=lenx*deltay-deltax*leny;
79         tfm=lenx;
80         f_update(fz,fm,tfz,tfm);
81     }
82     if(fm==1) cout<<fz<<endl; else cout<<fz<<'/'<<fm<<endl;
83     return 0;
84 }
View Code

E BPM136

给定一棵树,显然指定一些路径,所有通过这些路径的商队将会消失,每一对有序点对都会有一只商队,问最后剩下多少商队

考虑dfs序,那么每一条指定的路径相当于在一个正方形里面切掉两个矩形,而后二维数点即可(线段树+扫描线)

  1 /* ***********************************************
  2 Author        :BPM136
  3 Created Time  :2018/7/7 20:47:52
  4 File Name     :E_m.cpp
  5 ************************************************ */
  6  
  7 #include<iostream>
  8 #include<cstdio>
  9 #include<algorithm>
 10 #include<cstdlib>
 11 #include<cmath>
 12 #include<cstring>
 13 #include<vector>
 14 using namespace std;
 15  
 16 const int N = 100005;
 17  
 18 struct edge {
 19     int y,next;
 20 }e[N<<1];
 21 int last[N],ne=0;
 22  
 23 void add(int x,int y) {
 24     e[++ne].y=y; e[ne].next=last[x]; last[x]=ne;
 25 }
 26 void add2(int x,int y) {
 27     add(x,y);
 28     add(y,x);
 29 }
 30  
 31 int dfn[N],en[N],tim=0;
 32 int dep[N];
 33  
 34 int fa[N][21];
 35  
 36 struct node {
 37     int x,y;
 38     node() {}
 39     node(int _x,int _y) : x(_x),y(_y) {}
 40 };
 41 vector< node > vec1[N];
 42 vector< node > vec2[N];
 43  
 44 void vec_add(int x1,int x2,int y1,int y2) {
 45     vec1[x1].push_back(node(y1,y2));
 46     vec1[y1].push_back(node(x1,x2));
 47  
 48     vec2[x2+1].push_back(node(y1,y2));
 49     vec2[y2+1].push_back(node(x1,x2));
 50 }
 51  
 52 int n,m;
 53  
 54 void dfs(int x,int pre) {
 55     dfn[x]=++tim;
 56     dep[x]=dep[pre]+1;
 57  
 58     fa[x][0]=pre;
 59     for(int i=1;i<=20;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
 60     for(int i=last[x];i!=0;i=e[i].next) if(e[i].y!=pre) {
 61         dfs(e[i].y,x);
 62     }
 63     en[x]=tim;
 64 }
 65  
 66 namespace seg {
 67 #define LSON (k<<1)
 68 #define RSON (k<<1|1)
 69 #define MID ((l+r)/2)
 70  
 71     long long sum[N<<4];
 72     int lz[N<<4];
 73  
 74     void pushup(int k,int l,int r) {
 75         if(lz[k]) {
 76             sum[k]=r-l+1;
 77             return ;
 78         }
 79         if(l==r) {
 80             sum[k]=0;
 81             return ;
 82         }
 83         sum[k]=sum[LSON]+sum[RSON];
 84     }
 85  
 86     void add(int k,int l,int r,int ll,int rr,int val) {
 87         if(l==ll && r==rr) {
 88             lz[k]+=val;
 89             pushup(k,l,r);
 90             return ;
 91         }
 92         int mid=MID;
 93         if(rr<=mid) add(LSON,l,mid,ll,rr,val);
 94         else if(ll>mid) add(RSON,mid+1,r,ll,rr,val);
 95         else {
 96             add(LSON,l,mid,ll,mid,val);
 97             add(RSON,mid+1,r,mid+1,rr,val);
 98         }
 99         pushup(k,l,r);
100     }
101 }
102  
103 int main() {
104     scanf("%d%d",&n,&m);
105     for(int i=1;i<n;i++) {
106         int x,y;
107         scanf("%d%d",&x,&y);
108         add2(x,y);
109     }
110     dfs(1,0);
111     for(int i=1;i<=m;i++) {
112         int x,y;
113         scanf("%d%d",&x,&y);
114         if(dfn[x]>dfn[y]) swap(x,y);
115         if(dfn[x]<=dfn[y] && en[y]<=en[x]) {
116             int LCA=y;
117             for(int j=20;j>=0;j--) if(dep[fa[LCA][j]]>dep[x]) {
118                 LCA=fa[LCA][j];
119             }
120             if(en[LCA]<n) vec_add(en[LCA]+1,n,dfn[y],en[y]);
121             if(dfn[LCA]>1) vec_add(1,dfn[LCA]-1,dfn[y],en[y]);
122         } else vec_add(dfn[x],en[x],dfn[y],en[y]);
123     }
124  
125     long long ans=0;
126     for(int i=1;i<=n;i++) {
127         int sz=vec1[i].size();
128         for(int j=0;j<sz;j++) {
129             int x=vec1[i][j].x;
130             int y=vec1[i][j].y;
131             //cerr<<"????"<<endl;
132             //cerr<<1<<' '<<n<<' '<<x<<' '<<y<<endl;
133             seg::add(1,1,n,x,y,1);
134             //cerr<<"???"<<endl;
135         }
136         sz=vec2[i].size();
137         for(int j=0;j<sz;j++) {
138             int x=vec2[i][j].x;
139             int y=vec2[i][j].y;
140             seg::add(1,1,n,x,y,-1);
141         }
142         ans+=seg::sum[1];
143     }
144     ans=(long long) n*(n-1)-ans;
145     cout<<ans<<endl;
146     return 0;
147 }
View Code
原文地址:https://www.cnblogs.com/MyGirlfriends/p/9298449.html