ASC1 做题记录
A.
考虑相邻两个质数的差不会太大,于是我们从n/2开始暴力枚举即可,需要大数运算
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 def gcd(a,b): 2 if b==0: 3 return a 4 else: 5 return gcd(b,a%b) 6 7 f=open('china.in','r') 8 n=int(f.read()) 9 f.close() 10 for i in range(0,n//2): 11 if gcd(n//2-i,n)==1: 12 f=open('china.out','w') 13 f.write(str(n//2-i)) 14 f.close() 15 break
B.
上下界可行流裸题,一条边拆三条建图跑一下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define maxn 205 3 using namespace std; 4 typedef long long ll; 5 const int inf = 2e9+7; 6 int head[maxn],p,s,t; 7 struct edge 8 { 9 int to,next,id,f; 10 }e[maxn*maxn*4]; 11 void addedge(int u,int v,int f,int id) 12 { 13 e[p].to=v;e[p].id=0;e[p].f=f;e[p].next=head[u];head[u]=p++; 14 e[p].to=u;e[p].id=id;e[p].f=0;e[p].next=head[v];head[v]=p++; 15 } 16 int dis[maxn]; 17 bool bfs(int s,int t) 18 { 19 memset(dis,0,sizeof(dis)); 20 queue<int> q; 21 q.push(s); 22 dis[s]=1; 23 while(!q.empty()) 24 { 25 int u=q.front();q.pop(); 26 for(int i=head[u];i!=-1;i=e[i].next) 27 { 28 int v=e[i].to; 29 int f=e[i].f; 30 if(f&&!dis[v])dis[v]=dis[u]+1,q.push(v); 31 } 32 } 33 return dis[t]!=0; 34 } 35 int dfs(int u,int maxf,int t) 36 { 37 if(u==t)return maxf; 38 int tmp=0; 39 for(int i=head[u];i!=-1&&tmp<maxf;i=e[i].next) 40 { 41 int v=e[i].to; 42 int f=e[i].f; 43 if(f&&dis[v]==dis[u]+1) 44 { 45 int minn=min(maxf-tmp,f); 46 f=dfs(v,minn,t); 47 tmp+=f; 48 e[i].f-=f;e[i^1].f+=f; 49 } 50 } 51 if(!tmp)dis[u]=inf; 52 return tmp; 53 } 54 int dinic(int s,int t) 55 { 56 int ans=0; 57 while(bfs(s,t))ans+=dfs(s,inf,t); 58 return ans; 59 } 60 int n,m; 61 int L[maxn*maxn]; 62 int main() 63 { 64 freopen("cooling.in","r",stdin); 65 freopen("cooling.out","w",stdout); 66 scanf("%d%d",&n,&m); 67 s=201;t=202;p=0; 68 memset(head,-1,sizeof(head)); 69 for(int i=1;i<=m;++i) 70 { 71 int u,v,l,r; 72 scanf("%d%d%d%d",&u,&v,&l,&r); 73 L[i]=l; 74 addedge(s,v,l,0); 75 addedge(u,t,l,0); 76 addedge(u,v,r-l,i); 77 } 78 dinic(s,t); 79 bool yes=1; 80 for(int i=head[s];~i;i=e[i].next)if(e[i].f)yes=0; 81 for(int i=head[t];~i;i=e[i].next)if(e[i^1].f)yes=0; 82 if(yes) 83 { 84 puts("YES"); 85 for(int i=0;i<p;++i)L[e[i].id]+=e[i].f; 86 for(int i=1;i<=m;++i)printf("%d\n",L[i]); 87 } 88 else 89 { 90 puts("NO"); 91 } 92 }
C.
类似树上最大独立集的DP,记一下方案,注意卡空间
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define maxn 500005 3 using namespace std; 4 int n; 5 int head[maxn],c; 6 int to[maxn],nxt[maxn]; 7 void add(int u,int v) 8 { 9 to[++c]=v;nxt[c]=head[u];head[u]=c; 10 } 11 int pre[maxn]; 12 int dp[maxn][2]; 13 int Ans[maxn],cnt; 14 pair<int,int> tmp[maxn]; 15 int p; 16 void dfs(int u) 17 { 18 dp[u][0]=0;dp[u][1]=1; 19 for(int i=head[u];i;i=nxt[i])dfs(to[i]); 20 p=0; 21 for(int i=head[u];i;i=nxt[i]) 22 { 23 int v=to[i]; 24 dp[u][1]+=dp[v][0]; 25 dp[u][0]+=dp[v][0]; 26 tmp[++p]=make_pair(dp[v][1]-dp[v][0],v); 27 } 28 sort(tmp+1,tmp+p+1); 29 if(p>0) 30 { 31 int k=tmp[p].second; 32 if(dp[k][1]-dp[k][0]>0) 33 { 34 dp[u][0]+=dp[k][1]-dp[k][0]; 35 pre[u]=k; 36 } 37 } 38 } 39 void print(int u,int k) 40 { 41 if(k==1) 42 { 43 Ans[++cnt]=u; 44 for(int i=head[u];i;i=nxt[i])print(to[i],0); 45 } 46 else 47 { 48 if(pre[u])print(pre[u],1); 49 for(int i=head[u];i;i=nxt[i])if(to[i]!=pre[u])print(to[i],0); 50 } 51 } 52 int main() 53 { 54 freopen("grant.in","r",stdin); 55 freopen("grant.out","w",stdout); 56 scanf("%d",&n); 57 for(int i=2;i<=n;++i) 58 { 59 int x; 60 scanf("%d",&x); 61 add(x,i); 62 } 63 dfs(1); 64 printf("%d\n",dp[1][0]*1000); 65 print(1,0); 66 sort(Ans+1,Ans+cnt+1); 67 for(int i=1;i<=cnt;++i)printf("%d%c",Ans[i],(i==cnt)?'\n':' '); 68 }
D.
发现就是找朝外走两步的方案数,朝外走一步就是度数,朝外走两步就是相邻点度数求和
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define maxn 200005 3 using namespace std; 4 typedef long long ll; 5 int n,m; 6 vector<int> g[maxn]; 7 int d[maxn]; 8 int main() 9 { 10 freopen("matrix.in","r",stdin); 11 freopen("matrix.out","w",stdout); 12 scanf("%d%d",&n,&m); 13 for(int i=1;i<=m;++i) 14 { 15 int u,v; 16 scanf("%d%d",&u,&v); 17 g[u].push_back(v); 18 g[v].push_back(u); 19 d[u]++;d[v]++; 20 } 21 ll ans=0; 22 for(int i=1;i<=n;++i) 23 for(int v:g[i])ans+=d[v]; 24 cout<<ans<<endl; 25 }
E.
状压矩阵快速幂,这里可以直接十进制快速幂
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 char N[105]; 4 int m,mod; 5 struct Matrix 6 { 7 int a[35][35]; 8 void clear() 9 { 10 memset(a,0,sizeof(a)); 11 } 12 void init() 13 { 14 clear(); 15 for(int i=0;i<(1<<m);++i)a[i][i]=1; 16 } 17 }; 18 Matrix operator * (Matrix &A,Matrix &B) 19 { 20 Matrix C;C.clear(); 21 for(int j=0;j<(1<<m);++j) 22 for(int k=0;k<(1<<m);++k)if(B.a[k][j]) 23 for(int i=0;i<(1<<m);++i) 24 C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j])%mod; 25 return C; 26 } 27 Matrix fastpow(Matrix a,char *N) 28 { 29 int len=strlen(N); 30 Matrix ans;ans.init(); 31 for(int i=len-1;i>=0;--i) 32 { 33 int d=N[i]-'0'; 34 for(int j=1;j<=d;++j)ans=ans*a; 35 Matrix tmp=a; 36 for(int j=1;j<=9;++j)tmp=tmp*a; 37 a=tmp; 38 } 39 return ans; 40 } 41 int main() 42 { 43 freopen("nice.in","r",stdin); 44 freopen("nice.out","w",stdout); 45 scanf("%s",N); 46 scanf("%d%d",&m,&mod); 47 Matrix A;A.clear(); 48 for(int i=0;i<(1<<m);++i) 49 for(int j=0;j<(1<<m);++j) 50 { 51 int yes=1; 52 int si=(1<<m)-1-i,sj=(1<<m)-1-j; 53 for(int k=1;k<m;++k)if((i&(1<<k))&&(j&(1<<k))&&(i&(1<<(k-1)))&&(j&(1<<(k-1))))yes=0; 54 for(int k=1;k<m;++k)if((si&(1<<k))&&(sj&(1<<k))&&(si&(1<<(k-1)))&&(sj&(1<<(k-1))))yes=0; 55 A.a[i][j]=yes; 56 } 57 int Len=strlen(N); 58 N[Len-1]--; 59 for(int i=Len-1;i>=0;--i)if(N[i]<'0')N[i]+=10,N[i-1]--; 60 A=fastpow(A,N); 61 int ans=0; 62 for(int i=0;i<(1<<m);++i) 63 for(int j=0;j<(1<<m);++j)ans=(ans+A.a[i][j])%mod; 64 printf("%d\n",ans); 65 }
F.
把船的圆的半径加到岛上,那么就转化成一个点是否被一堆圆围住
有一个很容易观察到的转化是在有公共部分的两圆圆心之间连线,转化成点是否在一个多边形内
这里多边形不止一个,因此可以通过角度和判断,把边权赋为有向角度,那么角度和为负等价于有负环,Floyd跑一下就行了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 //LOOP 4 #define FF(i, a, b) for(int i = (a); i < (b); ++i) 5 #define FE(i, a, b) for(int i = (a); i <= (b); ++i) 6 #define FED(i, b, a) for(int i = (b); i>= (a); --i) 7 #define REP(i, N) for(int i = 0; i < (N); ++i) 8 #define CLR(A,value) memset(A,value,sizeof(A)) 9 #define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++) 10 //OTHER 11 #define SZ(V) (int)V.size() 12 #define PB push_back 13 #define MP make_pair 14 #define all(x) (x).begin(),(x).end() 15 //INPUT 16 #define RI(n) scanf("%d", &n) 17 #define RII(n, m) scanf("%d%d", &n, &m) 18 #define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k) 19 #define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p) 20 #define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q) 21 #define RS(s) scanf("%s", s) 22 //OUTPUT 23 #define WI(n) printf("%d\n", n) 24 #define WS(n) printf("%s\n", n) 25 //debug 26 //#define online_judge 27 #ifndef online_judge 28 #define debugt(a) cout << (#a) << "=" << a << " "; 29 #define debugI(a) debugt(a) cout << endl 30 #define debugII(a, b) debugt(a) debugt(b) cout << endl 31 #define debugIII(a, b, c) debugt(a) debugt(b) debugt(c) cout << endl 32 #define debugIV(a, b, c, d) debugt(a) debugt(b) debugt(c) debugt(d) cout << endl 33 #else 34 #define debugI(v) 35 #define debugII(a, b) 36 #define debugIII(a, b, c) 37 #define debugIV(a, b, c, d) 38 #endif 39 typedef long long LL; 40 typedef unsigned long long ULL; 41 typedef vector <int> VI; 42 const int INF = 0x3f3f3f3f; 43 const double eps = 1e-6; 44 const int MOD = 100000007; 45 const int MAXN = 1000010; 46 const double PI = acos(-1.0); 47 48 49 double torad(double deg) 50 { 51 return deg / 180 * PI; 52 } 53 inline int dcmp(double x) 54 { 55 if(fabs(x) < eps) return 0; 56 else return x < 0 ? -1 : 1; 57 } 58 struct Point 59 { 60 double x, y; 61 Point(double x=0, double y=0):x(x),y(y) { } 62 inline void read() 63 { 64 scanf("%lf%lf", &x, &y); 65 } 66 }; 67 typedef vector<Point> Polygon; 68 typedef Point Vector; 69 70 inline Vector operator + (Vector A, Vector B) 71 { 72 return Vector(A.x+B.x, A.y+B.y); 73 } 74 inline Vector operator - (Point A, Point B) 75 { 76 return Vector(A.x-B.x, A.y-B.y); 77 } 78 inline Vector operator * (Vector A, double p) 79 { 80 return Vector(A.x*p, A.y*p); 81 } 82 inline Vector operator / (Vector A, double p) 83 { 84 return Vector(A.x/p, A.y/p); 85 } 86 inline bool operator < (Point a, Point b) 87 { 88 return a.x < b.x || (a.x == b.x && a.y < b.y); 89 } 90 91 92 inline bool operator == (Point a, Point b) 93 { 94 return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0; 95 } 96 97 98 inline double Dot(Vector A, Vector B) 99 { 100 return A.x*B.x + A.y*B.y; 101 } 102 inline double Length(Vector A) 103 { 104 return sqrt(Dot(A, A)); 105 } 106 inline double Angle(Vector A, Vector B) 107 { 108 return acos(Dot(A, B) / Length(A) / Length(B)); 109 } 110 inline double angle(Vector v) 111 { 112 return atan2(v.y, v.x); 113 } 114 inline double Cross(Vector A, Vector B) 115 { 116 return A.x*B.y - A.y*B.x; 117 } 118 inline Vector Unit(Vector x) 119 { 120 return x / Length(x); 121 } 122 inline Vector Normal(Vector x) 123 { 124 return Point(-x.y, x.x) / Length(x); 125 } 126 inline Vector Rotate(Vector A, double rad) 127 { 128 return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad)); 129 } 130 inline double Area2(Point A, Point B, Point C) 131 { 132 return Cross(B-A, C-A); 133 } 134 template <class T> T sqr(T x) 135 { 136 return x * x ; 137 } 138 139 struct Circle 140 { 141 Point c; 142 double r; 143 Circle() {} 144 Circle(Point c, double r):c(c), r(r) {} 145 inline Point point(double a) 146 { 147 return Point(c.x+cos(a)*r, c.y+sin(a)*r); 148 } 149 inline void read() 150 { 151 scanf("%lf%lf%lf", &c.x, &c.y, &r); 152 } 153 }; 154 155 bool havecommonpoint(Circle A,Circle B) 156 { 157 return dcmp(sqr(A.c.x-B.c.x)+sqr(A.c.y-B.c.y)-sqr(A.r+B.r))<0; 158 } 159 #define maxn 305 160 int n; 161 Circle a[maxn]; 162 Point O; 163 double R; 164 double dis[maxn][maxn]; 165 int main() 166 { 167 freopen("out.in","r",stdin); 168 freopen("out.out","w",stdout); 169 scanf("%d",&n); 170 for(int i=1;i<=n;++i)a[i].read(); 171 O.read(); 172 scanf("%lf",&R); 173 for(int i=1;i<=n;++i)a[i].r+=R; 174 for(int i=1;i<=n;++i) 175 for(int j=1;j<=n;++j)dis[i][j]=1e18; 176 for(int i=1;i<=n;++i) 177 for(int j=1;j<=n;++j)if(i!=j&&havecommonpoint(a[i],a[j])) 178 { 179 double t=Angle(a[i].c-O,a[j].c-O); 180 if(dcmp(Cross(a[i].c-O,a[j].c-O))<0)t=-t; 181 dis[i][j]=min(dis[i][j],t); 182 } 183 for(int k=1;k<=n;++k) 184 for(int i=1;i<=n;++i) 185 for(int j=1;j<=n;++j)dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]+eps); 186 bool yes=1; 187 for(int i=1;i<=n;++i) 188 { 189 if(dcmp(dis[i][i])<=0)yes=0; 190 } 191 if(yes)puts("YES"); 192 else puts("NO"); 193 }
G.
类似LIS,线段树优化记录方案,注意细节
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define maxn 100005 3 using namespace std; 4 int n; 5 struct Point 6 { 7 int x,y,id; 8 }a[maxn]; 9 int dy[maxn],d; 10 bool operator < (Point A,Point B) 11 { 12 return A.x<B.x||(A.x==B.x&&A.y>B.y); 13 } 14 bool operator == (Point A,Point B) 15 { 16 return A.x==B.x&&A.y==B.y; 17 } 18 int maxv[maxn<<2],maxid[maxn<<2]; 19 void pushup(int rt) 20 { 21 if(maxv[rt<<1]>maxv[rt<<1|1])maxv[rt]=maxv[rt<<1],maxid[rt]=maxid[rt<<1]; 22 else maxv[rt]=maxv[rt<<1|1],maxid[rt]=maxid[rt<<1|1]; 23 } 24 void update(int rt,int l,int r,int pos,int v,int id) 25 { 26 if(l==r) 27 { 28 if(v>maxv[rt]) 29 { 30 maxv[rt]=v; 31 maxid[rt]=id; 32 } 33 return; 34 } 35 int mid=(l+r)>>1; 36 if(pos<=mid)update(rt<<1,l,mid,pos,v,id); 37 else update(rt<<1|1,mid+1,r,pos,v,id); 38 pushup(rt); 39 } 40 pair<int,int> query(int rt,int l,int r,int ql,int qr) 41 { 42 if(ql>qr)return make_pair(0,0); 43 if(ql<=l&&r<=qr)return make_pair(maxv[rt],maxid[rt]); 44 int mid=(l+r)>>1; 45 if(qr<=mid)return query(rt<<1,l,mid,ql,qr); 46 else if(ql>mid)return query(rt<<1|1,mid+1,r,ql,qr); 47 else 48 { 49 pair<int,int> ans1=query(rt<<1,l,mid,ql,qr),ans2=query(rt<<1|1,mid+1,r,ql,qr); 50 if(ans1.first>=ans2.first)return ans1; 51 else return ans2; 52 } 53 } 54 int dp[maxn],pre[maxn]; 55 void print(int u) 56 { 57 if(!u)return; 58 printf("%d ",a[u].id); 59 print(pre[u]); 60 } 61 int main() 62 { 63 freopen("people.in","r",stdin); 64 freopen("people.out","w",stdout); 65 scanf("%d",&n); 66 for(int i=1;i<=n;++i)scanf("%d%d",&a[i].x,&a[i].y),a[i].id=i,dy[++d]=a[i].y; 67 sort(a+1,a+n+1); 68 sort(dy+1,dy+d+1); 69 d=unique(dy+1,dy+d+1)-dy-1; 70 for(int i=1;i<=n;++i)a[i].y=lower_bound(dy+1,dy+d+1,a[i].y)-dy; 71 n=unique(a+1,a+n+1)-a-1; 72 for(int i=1;i<=n;++i) 73 { 74 pair<int,int> t=query(1,1,n,1,a[i].y-1); 75 dp[i]=t.first+1;pre[i]=t.second; 76 update(1,1,n,a[i].y,dp[i],i); 77 } 78 int ans=0; 79 for(int i=1;i<=n;++i)ans=max(ans,dp[i]); 80 for(int i=1;i<=n;++i)if(dp[i]==ans) 81 { 82 printf("%d\n",ans); 83 print(i); 84 break; 85 } 86 }
H.
可以转化为计数一些01串xor为0的方案数
这个东西就是选一个线性基,假设大小为r,那么剩下n-r个随便选,在线性基里总对应唯一方案,答案就是\(2^{n-r}\)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int m,n; 4 int prime[5005],cnt; 5 bool isprime(int x) 6 { 7 for(int i=2;i*i<=x;++i)if(x%i==0)return 0; 8 return 1; 9 } 10 void get(int N) 11 { 12 for(int i=2;i<=N;++i)if(isprime(i))prime[cnt++]=i; 13 } 14 bitset<100> a[105]; 15 void D(int id,int x) 16 { 17 for(int i=0;i<m;++i)if(x%prime[i]==0) 18 { 19 while(x%prime[i]==0) 20 { 21 x/=prime[i]; 22 a[id][i]=a[id][i]^1; 23 } 24 } 25 } 26 struct LinearBasis 27 { 28 bitset<100> basis[105]; 29 int r; 30 void clear() 31 { 32 r=0; 33 for(int i=0;i<105;++i)basis[i].reset(); 34 } 35 inline void insert(bitset<100> val) 36 { 37 for(int i=99;i>=0;i--)if(val[i]) 38 { 39 if(basis[i].count()==0) 40 { 41 basis[i]=val; 42 r++; 43 break; 44 } 45 val^=basis[i]; 46 } 47 } 48 }A; 49 int out[105]; 50 void print(__int128 x) 51 { 52 if(!x) 53 { 54 puts("0"); 55 return; 56 } 57 int p=0; 58 while(x) 59 { 60 out[++p]=x%10; 61 x/=10; 62 } 63 for(int i=p;i>=1;--i)printf("%d",out[i]); 64 } 65 int main() 66 { 67 freopen("rsa.in","r",stdin); 68 freopen("rsa.out","w",stdout); 69 scanf("%d%d",&m,&n); 70 get(5000); 71 A.clear(); 72 for(int i=1;i<=n;++i) 73 { 74 int x; 75 scanf("%d",&x); 76 D(i,x); 77 A.insert(a[i]); 78 } 79 int r=A.r; 80 __int128 ans=1; 81 for(int i=1;i<=n-r;++i)ans=ans*2; 82 ans-=1; 83 print(ans); 84 }