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

 

posted @ 2019-09-28 17:51  ninelifecat  阅读(170)  评论(0编辑  收藏  举报