zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",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
    ",ans); 
        return 0;
    }
    

      


    总结: T1:考试竟然写挂了2次才写出来。。。

                T2:中途msr过来说:这不就是个傻X O(n)的树上差分吗,然后我最后还是头铁的写了线段树。。。然后成了最长最慢的

                T3:中途gmt过来说:您还没AK啊,然后告诉我我的网络流思想是对的,然后我被忽悠的到最后也没建出图。。。。

  • 相关阅读:
    tar命令,vi编辑器
    Linux命令、权限
    Color Transfer between Images code实现
    利用Eclipse使用Java OpenCV(Using OpenCV Java with Eclipse)
    Matrix Factorization SVD 矩阵分解
    ZOJ Problem Set
    Machine Learning
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
  • 原文地址:https://www.cnblogs.com/ninelifecat/p/11604130.html
Copyright © 2011-2022 走看看