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啊,然后告诉我我的网络流思想是对的,然后我被忽悠的到最后也没建出图。。。。

  • 相关阅读:
    git 专题
    Android yyyymmdd转成yyyy-MM-dd格式
    Android LayoutInflater.from(context).inflate
    Android TextView内容过长加省略号,点击显示全部内容
    Android 标题栏封装
    Android 自定义Android带图片和文字的ImageButton
    Android 防止按钮连续点击的方法(Button,ImageButton等)
    Android 动态改变布局属性RelativeLayout.LayoutParams.addRule()
    Android ActionBar的Overlay模式如何不遮盖顶部内容的问题
    Android 时间轴TimeLine
  • 原文地址:https://www.cnblogs.com/ninelifecat/p/11604130.html
Copyright © 2011-2022 走看看