9.23&9.27
9.23:
A:一开始以为是2*(n-1),推着推着就发现了问题,如果一开始封闭一个点,并不断进行此操作,就是(n-1)(n+2)/2,很明显后者更大
#include<cstdio> using namespace std; int main() { long long n; scanf("%lld",&n); n=(n-1)+n*(n-1)/2; printf("%lld",n); return 0; }
B:二分图匹配,分成奇数偶数连边就可以了,最后是总点数见最大匹配
#include<cstdio> #include<queue> #include<cstring> #define int long long using namespace std; const int INF=0x7f7f7f7f; int dep[100010],head[100010],inq[100010],cur[100010]; int top=1,maxflow=0; int a[100010]; int n,m=0,s,t,w; struct Node { int v; int val; int next; }node[200010]; void add(int u,int v,int val) { node[++top].v=v; node[top].val=val; node[top].next=head[u]; head[u]=top; } int gcd(int x,int y) { int r; if(x<y) { x^=y^=x^=y; } do { r=x%y; x=y; y=r; }while(r); return x; } bool bfs() { memset(dep,0,sizeof(dep)); dep[s]=1; queue<int>q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i;i=node[i].next) { int d=node[i].v; if(!dep[d]&&node[i].val) { dep[d]=dep[u]+1; if(d==t) return 1; q.push(d); } } } return 0; } int dfs(int u,int flow) { int rlow=0; if(u==t) return flow; for(int i=head[u];i;i=node[i].next) { int d=node[i].v; if(node[i].val&&dep[d]==dep[u]+1) { if((rlow=dfs(d,min(flow,node[i].val)))) { node[i].val-=rlow; node[i^1].val+=rlow; return rlow; } else dep[d]=0; } } return 0; } int dinic() { int lowflow; while(bfs()) { while((lowflow=dfs(s,INF))) maxflow+=lowflow; } return maxflow; } signed main() { //freopen("c4.in","r",stdin); //freopen("5.out","w",stdout); scanf("%lld",&n); s=0; t=n+1; for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if(gcd(a[i],a[j])==1 && gcd(a[i]+1,a[j]+1)==1) { if(a[i]%2==1) { add(i,j,1); add(j,i,0); } else { add(j,i,1); add(i,j,0); } } } } for(int i=1;i<=n;i++) { if(a[i]%2==1) { add(s,i,1); add(i,s,0); } else { add(i,t,1); add(t,i,0); } } printf("%lld",n-dinic()); return 0; }
C:先考虑有0的,有0的就是两边各自有至少1个0。然后两边都不填0,我们按照2,3,5,7进行压位,也就是分别维护每个质数的次数,进行DP即可。
然后这题就发现竟然爆了long long (毒瘤的yzx)
总结:T1:考试时很顺利的推出
T2:看出是个二分图,然后忘了分奇偶性就挂了
T3:考试推了出来,然后因为毒瘤的出题人要你高精,然后就发现和暴力一个分。。。
9.27:
A :对着图找规律然后模拟这个过程就好了
#include<cstdio> #define int long long using namespace std; signed main() { //freopen("glucagon.in","r",stdin); //freopen("glucagon.out","w",stdout); int t; scanf("%lld",&t); while(t--) { int l,x; scanf("%lld%lld",&l,&x); int qwq=l; l=x; x=qwq-x; int ans=0; while(1) { //printf("%lld %lld\n",l,x); if(l%x==0) { ans+=(l/x)*3*x; break; } else { int cnt=l%x; ans+=(l/x)*3*x; l=x; x=cnt; } } printf("%lld\n",ans); } return 0; }
B:维护两棵线段树,然后一棵进行操作,另一棵记录就可以了
#include<cstdio> #include<cctype> #include<algorithm> #define ll long long const int mod=1000000007ll; using namespace std; int n,q,on[100010],tw[100010],cnt,cnt1,cnt2; int y[100010],z[100010],x[100010],ans[100010]; int ls(int fu){return fu<<1;} int rs(int fu){return fu<<1|1;} int read() { int f=1,x=0; char ch=' '; for(;!isdigit(ch);ch=getchar())if(ch=='-')f*=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return f*x; } struct Node { int l,r,l1,r1; ll tag; }a[1000010]; struct Node2 { int l,r; ll tag,sum; }t[1000010]; void build(int fu,int l,int r) { a[fu].l=l;a[fu].r=r; if(l==r) { a[fu].l1=y[l]; a[fu].r1=z[l]; if(x[l]==1) on[++cnt1]=fu; else tw[++cnt2]=fu; a[fu].tag=1;return; } int mid=l+r>>1; build(ls(fu),l,mid); build(rs(fu),mid+1,r); a[fu].tag=0; } void build2(int fu,int l,int r) { t[fu].l=l;t[fu].r=r; if(l==r){ans[++cnt]=fu;return;} int mid=l+r>>1; build2(ls(fu),l,mid); build2(rs(fu),mid+1,r); a[fu].tag=0; } void update(int fu) { t[fu].sum=t[ls(fu)].sum+t[rs(fu)].sum; t[fu].sum%=mod; } void push(int fu) { if(a[fu].tag) { a[ls(fu)].tag+=a[fu].tag;a[ls(fu)].tag%=mod; a[rs(fu)].tag+=a[fu].tag;a[rs(fu)].tag%=mod; a[fu].tag=0; } } void push2(int fu) { if(!t[fu].tag)return; t[ls(fu)].tag+=t[fu].tag;t[ls(fu)].tag%=mod; t[rs(fu)].tag+=t[fu].tag;t[rs(fu)].tag%=mod; t[ls(fu)].sum+=(1ll*(t[ls(fu)].r-t[ls(fu)].l+1)*t[fu].tag)%mod;t[ls(fu)].sum%=mod; t[rs(fu)].sum+=(1ll*(t[rs(fu)].r-t[rs(fu)].l+1)*t[fu].tag)%mod;t[rs(fu)].sum%=mod; t[fu].tag=0; } void fuck(int s,int fu) { if(s==fu)return; push(s); int mid=a[s].l+a[s].r>>1; if(a[fu].l<=mid)fuck(ls(s),fu);else fuck(rs(s),fu); } void work1(int fu) { if(a[fu].l-a[fu].r) push(fu),work1(ls(fu)),work1(rs(fu)); } void work2(int fu) { if(t[fu].l-t[fu].r) push2(fu),work2(ls(fu)),work2(rs(fu)); } void add(int fu,int l,int r,ll s) { if(l<=a[fu].l&&r>=a[fu].r) { a[fu].tag+=s; a[fu].tag%=mod; return; } int mid=a[fu].l+a[fu].r>>1;push(fu); if(l<=mid)add(ls(fu),l,r,s); if(r>mid)add(rs(fu),l,r,s); } void add2(int fu,int l,int r,ll s) { if(l<=t[fu].l&&r>=t[fu].r) { t[fu].tag+=s;t[fu].tag%=mod; t[fu].sum+=(1ll*(t[fu].r-t[fu].l+1)*s)%mod;t[fu].sum%=mod; return; } int mid=t[fu].l+t[fu].r>>1; push2(fu); if(l<=mid) add2(ls(fu),l,r,s); if(r>mid) add2(rs(fu),l,r,s); update(fu); } int main() { // freopen("insulin.in","r",stdin); // freopen("insulin.out","w",stdout); n=read(),q=read(); for(int i=1;i<=q;i++) { x[i]=read(); y[i]=read(); z[i]=read(); } build(1,1,q); for(int i=cnt2;i>=1;i--) { add(1,a[tw[i]].l1,a[tw[i]].r1,a[tw[i]].tag); if(i!=1) fuck(1,tw[i-1]); } work1(1); build2(1,1,n); for(int i=1;i<=cnt1;i++) add2(1,a[on[i]].l1,a[on[i]].r1,a[on[i]].tag); work2(1); for(int i=1;i<=n;i++) printf("%lld ",t[ans[i]].sum); return 0; }
C:一开始以为又是网络流,然后最后发现是求走遍所有点的基环树
#include<cstdio> #include<algorithm> #include<cctype> #include<cmath> using namespace std; int read() { int f=1,x=0; char ch=' '; for(;!isdigit(ch);ch=getchar())if(ch=='-')f*=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return f*x; } struct node { int x,y,w; }p[200010]; int n,m,ans; int fa[200010],d[200010]; bool cmp(node a,node b) { return a.w>b.w; } int find(int x) { if(x==fa[x]) return x; return fa[x]=find(fa[x]); } int main() { m=read(),n=read(); for(int i=1;i<=m;++i) { int x=read(),y=read(),z=read(); p[i].x=x,p[i].y=y,p[i].w=z; } sort(p+1,p+m+1,cmp); for(int i=1;i<=n;++i) fa[i]=i,d[i]=1; for(int i=1;i<=m;++i) { int x=find(p[i].x),y=find(p[i].y); if(x!=y&&(d[x]!=0||d[y]!=0)) fa[y]=x,ans+=p[i].w,d[x]=d[x]&d[y]; else if(x==y&&d[x]) d[x]=0,ans+=p[i].w; } printf("%d\n",ans); return 0; }
总结: T1:考试竟然写挂了2次才写出来。。。
T2:中途msr过来说:这不就是个傻X O(n)的树上差分吗,然后我最后还是头铁的写了线段树。。。然后成了最长最慢的
T3:中途gmt过来说:您还没AK啊,然后告诉我我的网络流思想是对的,然后我被忽悠的到最后也没建出图。。。。