ASC1 做题记录

A.

考虑相邻两个质数的差不会太大,于是我们从n/2开始暴力枚举即可,需要大数运算

 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
View Code

B.

上下界可行流裸题,一条边拆三条建图跑一下

 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 }
View Code

C.

类似树上最大独立集的DP,记一下方案,注意卡空间

 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 }
View Code

D.

发现就是找朝外走两步的方案数,朝外走一步就是度数,朝外走两步就是相邻点度数求和

 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 }
View Code

E.

状压矩阵快速幂,这里可以直接十进制快速幂

 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 }
View Code

F.

把船的圆的半径加到岛上,那么就转化成一个点是否被一堆圆围住

有一个很容易观察到的转化是在有公共部分的两圆圆心之间连线,转化成点是否在一个多边形内

这里多边形不止一个,因此可以通过角度和判断,把边权赋为有向角度,那么角度和为负等价于有负环,Floyd跑一下就行了

  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 }
View Code

G.

类似LIS,线段树优化记录方案,注意细节

 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 }
View Code

H.

可以转化为计数一些01串xor为0的方案数

这个东西就是选一个线性基,假设大小为r,那么剩下n-r个随便选,在线性基里总对应唯一方案,答案就是\(2^{n-r}\)

 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 }
View Code

 

posted @ 2020-11-27 00:43  幽蝶  阅读(105)  评论(0编辑  收藏  举报