NOIP2018退役总结

长存不灭的过去——逐渐消失的未来

退役前写了点模板,留作纪念,也祝我NOIP2018++RP

没时间了,就800行吧!

#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
inline int read()//读入优化 
{
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-f;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
priority_queue<int >q;//优先队列 
int priorityqueue()
{
	q.push();
	q.top();
	q.pop();
	q.back();
	q.empty(); 
}
void add(int a,int b,int c)//建图 
{
	p++;
	to[p]=b;
	next[p]=last[a];
	last[a]=p;
	w[p]=c;
}
int find(int k)//find函数 
{
	if(fa[k]==k)return k;
	return fa[k]=find(fa[k]);
}
void merge(int a,int b)//合并两个集合 
{
	int a=find(a),b=find(b);
	if(a!=b)fa[a]=b;
}
int gcd(int a,int b)//求最大公约数 
{
	if(!b)return a;
	return gcd(b,a%b);
}
int exgcd(int a,int b,int &x,int &y)//求a在%b意义下的逆元 
{
	if(b)
	{
		exgcd(b,a%b,y,x);
		y-=(a/b)*x;
	}
	else
	{
		x=1;y=0;
	}
} 
int lcm(int a,int b)//求最小公倍数 
{
	return a/gcd(a,b)*b;
}
int erfen()
{
	l=0,r=max;
	while(l<r)
	{
		int mid=(l+r)>>1;
		if(check(mid))l=mid+1;
		else r=mid;
	}
	return l;
}
int ksm(int a,int b)//快速幂 
{
	int ans=1,c=a;
	while(b!=0)
	{
		if(b&1!=0)ans*=c;
		c*=c;
		b>>1;
	}
	return ans;
}
int ola(int n)//欧拉筛 
{
	int cnt=0;
	for(int i=2;i<=n;i++)
	{
		if(!v[i])p[cnt++]=i;
		for(int j=0;j<cnt&&i*p[j]<=n;j++)
		{
			v[i*p[j]]=1;
			if(i%p[j]==0)break;
		}
	}
	return cnt;
}
inline int read()//取模快读_有理数取余用 
{
    char ch=getchar();int x=0;
    while(ch<'0'||ch>'9')ch=getchar();
    while(ch<='9'&&ch>='0'){x=x*10+ch-'0';x%=mod;ch=getchar();}
    return x;
}
int ylsqy()//有理数取余 
{
    a=read();b=read();
    if(b==0)
    {
        cout<<"Angry!";
        return 0;
    }
    exgcd(b,mod,x,y); 
    cout<<(a*(x+mod)%mod+mod)%mod;
}
int jcdp()//基础dp
{
	for(int i=1;i<=n;i++)//01背包 
	for(int j=m;j>=w[i];j--)
	f[j]=max(f[j],f[j-w[i]]+v[i]);
	
	for(int i=1;i<=n;i++)//完全背包 
	for(int j=w[i];j<=m;j++)
	f[j]=max(f[j],f[j-w[i]]+v[i]);
	
	for(int i=1;i<=n;i++)//最长不下降子序列(滚动数组优化) 
	{
		mx=0;
		for(int j=1;j<=a[i];j++)
		mx=max(mx,f[j]);
		f[a[i]]=mx+1;
	}
	
	for(int i=1;i<=n;i++)//最长公共子序列 
	for(int j=1;j<=n;j++)
	{
		f[i][j]=max(f[i][j-1],f[i-1][j]);
		if(a[i]==b[j])f[i][j]=max(f[i][j],f[i-1][j-1]+1);
	}
} 
int spfa()//单源最短路径 
{
	n=read(),m=read(),s=read(),e=read();
	for(int i=1;i<=n;i++)
	{
		a=read(),b=read(),c=read();
		add(a,b,c);
		add(b,a,c);
	}
	for(int i=1;i<=n;i++)ans[i]=2147483647;
	ans[s]=0;v[s]=1;q[1]=s;h=0;t=1;
	while(h<t)
	{
		h++;
		int i=q[h];
		v[i]=0;
		int pp=last[i];
		while(pp)
		{
			if(ans[to[pp]]>ans[i]+w[pp])
			{
				ans[to[pp]]=ans[i]+w[pp];
				if(!v[to[pp]])
				{
					v[to[pp]]=1;
					t++;
					q[t]=to[pp];
				}
			}
			pp=next[pp];
		}
	}
}
int floyd()//多源最短路 
{
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
		map[i][j]=2147483647;
	for(int i=1;i<=n;i++)map[i][i]=0;
	for(int k=1;k<=n;k++)
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	{
		if(map[i][j]>map[i][k]+map[k][j])
		map[i][j]=map[i][k]+map[k][j];
	}
}
void add(int a,int b,int c)//次短路 
{
    p++;
    to[p]=b;
    next[p]=last[a];
    last[a]=p;
    w[p]=c;
    star[p]=a;
}
void spfa ()
{
    for(int i=1;i<=n;i++)
    ans[i]=20010129;   
    q[1]=1;
    ans[1]=0;
    v[1]=1;h=0;t=1;
    while(h<t)
    {
        h++;
        int i=q[h];
        v[i]=0;
        int pp=last[i];
        while(pp)
        {
            if(ans[to[pp]]>w[pp]+ans[i])
            {
                ans[to[pp]]=w[pp]+ans[i];
                if(e!=1)per[to[pp]]=pp;
                if(!v[to[pp]])
                {
                    t++;
                    q[t]=to[pp];
                    v[to[pp]]=1;
                }
            }
            pp=next[pp];
        }
    }
    e=1;
}
int cdl()
{
    memset(per,-1,sizeof per );
    n=read(),m=read(); 
    for(int i=1;i<=m;i++)
    {
        a=read(),b=read(),c=read();
        add(a,b,c);
        add(b,a,c);
    }
    int tm=n;
    spfa();
    while(per[tm]!=-1)
    {
    	r=w[per[tm]];
    	w[per[tm]]=20010129;
    	spfa();
    	if(ans[n]!=20010129)
        mx=max(mx,ans[n]);
    	w[per[tm]]=r;
    	tm=star[per[tm]];
    }
    cout<<mx;
    return 0;
}

int nim()//nim游戏 
{
	int ans=0;
	for(int i=1;i<=n;i++)a=read(),ans^=x;
	if(ans)cout<<"Yes";
	else cout<<"No";
}
int feishu()//肥鼠定理 
{
	n=read();
    for(int i=1;i<=n;i++)
    {
        x=read();
        if(x<0)x=-x;
        ans=gcd(ans,x);//gcd参照上方 
    }
    cout<<ans;
}
int lucas(int x,int y)//卢卡斯定理 
{
    if(x<y) return 0;
    else if(x<p) return b[x]*a[y]*a[x-y]%p;
    else return lucas(x/p,y/p)*lucas(x%p,y%p)%p;
}
int LUCAS()
{
	T=read();
    while(T--)
    {
        n=read(),m=read(),p=read();
        a[0]=1,a[1]=1,b[0]=1,b[1]=1;
        for(int i=2;i<=n+m;i++)b[i]=b[i-1]*i%p;
        for(int i=2;i<=n+m;i++)a[i]=(p-p/i)*a[p%i]%p;
        for(int i=2;i<=n+m;i++)a[i]=a[i-1]*a[i]%p;
        cout<<lucas(n+m,m)<<"\n";
    }
} 
queue<int >q;//拓扑求最长路 
int topu()
{
	n=read(),m=read();
	for(int i=1;i<=m;i++)
	{
		a=read(),b=read(),c=read();
		add(a,b,c);ru[b]++;
	}
	for(int i=1;i<=n;i++)if(!ru[i])q.push(i);
	while(!q.empty())
	{
		x=q.front();q.pop();
		for(int i=last[x];i;i=next[i])
		{
			if(f[to[i]]<f[x]+w[i])f[to[i]]=f[x]+w[i];
			ru[to[i]]--;
			if(!ru[to[i]])q.push(to[i]);
		}
	}
	for(int i=1;i<=n;i++)if(ans<f[i])ans=f[i];
	cout<<ans;
}
int lca_dfs(int k)//求LCA 
{
    for(int i=1;(1<<i)<=d[k];i++)
        fa[k][i]=fa[fa[k][i-1]][i-1];
    for(int i=last[k];i;i=next[i])
    {
        if(!v[to[i]])
        {
            v[to[i]]=1;
            if(d[to[i]]==0)
            {
                d[to[i]]=d[k]+1;
                fa[to[i]][0]=k;
                lca_dfs(to[i]);
            }
        }
    }
}
int lca()
{
	if(d[x]<d[y])swap(x,y);
    while(d[x]>d[y])x=fa[x][lg[d[x]-d[y]]-1];
    if(x==y)return x;
    for(int k=lg[d[x]];k>=0;k--)
    if(fa[x][k]!=fa[y][k])
    {
        x=fa[x][k];
        y=fa[y][k];
    }
    return fa[x][0];
}
int LCA()
{
	n=read();m=read();s=read();
    for(int i=1;i<n;i++)
    {
        a=read();b=read();
        add(a,b);add(b,a);
    }
    v[s]=1;dfs(s);
    for(int i=1;i<=n;i++)
    lg[i]=lg[i-1]+(1<<lg[i-1]==i);
    for(int i=1;i<=m;i++)
    {
        a=read();b=read();
        cout<<lca(a,b)<<"\n"; 
    }
    return 0;
}
bool spfa_panfuhuan()
{
    for(int i=1;i<=n;i++)ans[i]=214748364,q[i]=0,v[i]=0;
    ans[1]=0;q[1]=1;v[1]=1,cnt[1]=1;h=0,t=1;
    while(h<t)
    {
        h++;
        int i=q[h];
        if(cnt[i]>n)return 1;
        v[i]=0;
        pp=last[i];
        while(pp)
        {
            if(ans[to[pp]]>ans[i]+w[pp])
            {
                ans[to[pp]]=ans[i]+w[pp];
                cnt[to[pp]]=cnt[i]+1;
                if(cnt[to[pp]]>n)return 1;
                if(!v[to[pp]])
                {
                    v[to[pp]]++;
                    t++;
                    q[t]=to[pp];
                }
            }
            pp=next[pp];
        }
    }
    return 0;
}
struct AC //最小生成树 
{
    int a,b,v;
}lxx[N];
bool cmp(AC const a,AC const b)
{
    return a.v<b.v;
}
int find (int k)
{
    if(fa[k]==k)return k;
    return fa[k]=find(fa[k]);
}
void kruskal()
{
    for(int i=1;i<=m;i++)
    {
        x=find(lxx[i].a);
        y=find(lxx[i].b);
        if(x!=y)
        {
            ans+=lxx[i].v;
            p++;
            fa[x]=y;
            if(p==n)
            {
                cout<<ans;
                return ;
            }
        }
    }
}
int KRUSKAL()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=1;i<=m;i++)lxx[i].a=read(),lxx[i].b=read(),lxx[i].v=read();
    sort(lxx+1,lxx+m+1,cmp);
    kruskal();
}
queue<int> q;//缩点,建DAG新图,求最大点权路径 
struct ac
{
    int to,next,last;
}e[500010];
void add(int a,int b)
{
	p++;
	e[p].to=b;
	e[p].next=e[a].last;
	e[a].last=p;
}
int tarjan(int x)
{
	low[x]=dfn[x]=++dep;
	stack[++top]=x;v[x]=1;
	for(int i=e[x].last;i;i=e[i].next)
	{
		if(!dfn[e[i].to])tarjan(e[i].to),low[x]=min(low[x],low[e[i].to]);
		else if(v[e[i].to])low[x]=min(low[x],low[e[i].to]);
	}
	if(low[x]==dfn[x])
	{
		now[x]=++tot;
		v[x]=0;
		while(stack[top]!=x)
		{
			now[stack[top]]=tot;
			v[stack[top--]]=0;
		}
		top--;
	}
}
void build()
{
	for(int i=1;i<=n;i++)
	{
		f[now[i]]=sum[now[i]];
		for(int j=e[i].last;j;j=e[j].next)
		{
			if(now[i]!=now[e[j].to])
			{
				next[j]=last[now[i]];
				last[now[i]]=j;
				ru[now[e[j].to]]++;
			}
		}
	}
}
void tuopu()
{
	for(int i=1;i<=n;i++)
	if(!ru[now[i]]&&!v[now[i]])q.push(now[i]),v[now[i]]=1;
	while(!q.empty())
	{
		int x=q.front();q.pop();
		for(int i=last[x];i;i=next[i])
		{
			f[now[e[i].to]]=max(f[now[e[i].to]],f[x]+sum[now[e[i].to]]);
			ru[now[e[i].to]]--;
			if(!ru[e[i].to]&&!v[e[i].to])q.push(now[e[i].to]),v[now[e[i].to]]=1;
		}
	}
}
int TARJAN()
{
	n=read(),m=read();
	for(int i=1;i<=n;i++)w[i]=read();
	for(int i=1;i<=m;i++)a=read(),b=read(),add(a,b);
	for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
	for(int i=1;i<=n;i++)sum[now[i]]+=w[i];
	build();tuopu();
	for(int i=1;i<=n;i++)ans=max(ans,f[now[i]]);
	cout<<ans; 
}
struct tr//线段树1
{
    int l,r;
    long long v,ad;
}s[2000001];
void build(int i,int l,int r)
{
    s[i].l=l;s[i].r=r;
    if(l==r)
    {
        s[i].v=a[l];return;
    }
    build(i*2,l,(l+r)/2);
    build(i*2+1,(l+r)/2+1,r);
    s[i].v=s[i*2].v+s[i*2+1].v;
}
void ask(int i,int ll,int rr)
{
    if(s[i].ad!=0)
    {
        s[i].v+=s[i].ad*(s[i].r-s[i].l+1);
        s[2*i].ad+=s[i].ad;
        s[2*i+1].ad+=s[i].ad;
        s[i].ad=0;
    }
    if(s[i].l>=ll&&s[i].r<=rr)
    {
        sum+=s[i].v;
        return;
    }
    int kk=i*2;
    if(s[kk].r>=ll)ask(kk,ll,rr);
    if(s[kk+1].l<=rr)ask(kk+1,ll,rr);
}
void add(int i,int ll,int rr,int x)
{
    if(s[i].l>=ll&&s[i].r<=rr)
    {
        s[i].ad+=x;
        return;
    }
    if(ll>=s[i].l&&rr<=s[i].r)s[i].v+=x*(rr-ll+1);
    else s[i].v+=x*(min(abs(s[i].r-ll+1),abs(rr-s[i].l+1)));
    if(s[i].ad!=0)
    {
        s[i].v+=(s[i].r-s[i].l+1)*s[i].ad;
        s[2*i].ad+=s[i].ad;
        s[2*i+1].ad+=s[i].ad;
        s[i].ad=0;
    }
    int kk=i*2;
    if(s[kk].r>=ll)add(kk,ll,rr,x);
    if(s[kk+1].l<=rr)add(kk+1,ll,rr,x);
}
int xds1()
{
	n=read(),m=read();
    for(int i=1;i<=n;i++)a[i]=read();
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
        int k;k=read();
        if(k==1)
        {
            int b,c,d;
            b=read(),c=read(),d=read();
            add(1,b,c,d);
        }
        if(k==2)
        {
            int b,c;
            b=read(),c=read();
            sum=0;
            ask(1,b,c);
            if(sum<=0)cout<<0<<endl; 
            else cout<<sum<<endl;
        }
    }
	//1.将某区间每一个数加上x
	//2.求出某区间每一个数的和
}
void add(int x,int k)//树状数组1
{
    while(x<=n)
    {
        tree[x]+=k;
        x+=x&-x;
    }
}
int sum(int x)
{
    int ans=0;
    while(x!=0)
    {
        ans+=tree[x];
        x-=x&-x;
    } 
    return ans;
}
int szsz1()
{
	n=read(),m=read();
    for(int i=1;i<=n;i++)
    {
        a=read();
        add(i,a);//第i项的值为a; 
    } 
    for(int i=1;i<=m;i++)
    {
        a=read(),b=read(),c=read();
        if(a==1)add(b,c);
        else cout<<sum(c)-sum(b-1)<<endl;//前缀和求出b--c间每个数的和; 
    }
	//1.将某一个数加上x
	//2.求出某区间每一个数的和
} 
struct AC//线段树2 
{
    long long ans,mul,add;
}lxx[N*4];
void bt(int rt,int l,int r)
{
    lxx[rt].mul=1;
    lxx[rt].add=0;
    if(l==r)lxx[rt].ans=a[l];
    else
    {
        int mid=(l+r)/2;
        bt(rt*2,l,mid);
        bt(rt*2+1,mid+1,r);
        lxx[rt].ans=lxx[rt*2].ans+lxx[rt*2+1].ans;
    }
    lxx[rt].ans%=p;
    return ;
}
void pushdown(int rt,int l,int r)
{
    int mid=(l+r)/2;
    lxx[rt*2].ans=(lxx[rt*2].ans*lxx[rt].mul+lxx[rt].add*(mid-l+1))%p;
    lxx[rt*2+1].ans=(lxx[rt*2+1].ans*lxx[rt].mul+lxx[rt].add*(r-mid))%p;
    lxx[rt*2].mul=(lxx[rt*2].mul*lxx[rt].mul)%p;
    lxx[rt*2+1].mul=(lxx[rt*2+1].mul*lxx[rt].mul)%p;
    lxx[rt*2].add=(lxx[rt*2].add*lxx[rt].mul+lxx[rt].add)%p;
    lxx[rt*2+1].add=(lxx[rt*2+1].add*lxx[rt].mul+lxx[rt].add)%p;
    lxx[rt].mul=1;
    lxx[rt].add=0;
    return ;
}
void udmul(int rt,int ll,int rr,int l,int r,long long k)
{
    if(r<ll||rr<l)return;
    if(l<=ll&&rr<=r)
    {
        lxx[rt].ans=(lxx[rt].ans*k)%p;
        lxx[rt].mul=(lxx[rt].mul*k)%p;
        lxx[rt].add=(lxx[rt].add*k)%p;
        return ;
    }
    pushdown(rt,ll,rr);
    int mid=(ll+rr)/2;
    udmul(rt*2,ll,mid,l,r,k);
    udmul(rt*2+1,mid+1,rr,l,r,k);
    lxx[rt].ans=(lxx[rt*2].ans+lxx[rt*2+1].ans)%p;
    return ;
}
void udadd(int rt,int ll,int rr,int l,int r,long long k)
{
    if(r<ll||rr<l)return ;
    if(l<=ll&&rr<=r)
    {
        lxx[rt].add=(lxx[rt].add+k)%p;
        lxx[rt].ans=(lxx[rt].ans+k*(rr-ll+1))%p;
        return ;
    }
    pushdown(rt,ll,rr);
    int mid=(ll+rr)/2;
    udadd(rt*2,ll,mid,l,r,k);
    udadd(rt*2+1,mid+1,rr,l,r,k);
    lxx[rt].ans=(lxx[rt*2].ans+lxx[rt*2+1].ans)%p;
    return ;
}
long long ask(int rt,int ll,int rr,int l,int r)
{
    if(r<ll||rr<l ) return 0;
    if(l<=ll&&rr<=r)return lxx[rt].ans;
    pushdown(rt,ll,rr);
    int mid=(ll+rr)/2;
    return (ask(rt*2,ll,mid,l,r)+ask(rt*2+1,mid+1,rr,l,r))%p;
}
int xds2()
{
	n=read();m=read();p=read();
    for(int i=1;i<=n;i++)a[i]=read();
    bt(1,1,n);
    for(int i=1;i<=m;i++)
    {
        ch=read();
        if(ch==1)
        {
            x=read();y=read();k=read();
            udmul(1,1,n,x,y,k);
        }
        if(ch==2)
        {
            x=read();y=read();k=read();
            udadd(1,1,n,x,y,k);
        }
        if(ch==3)
        {
            x=read();y=read();
            cout<<ask(1,1,n,x,y)%p<<"\n";
        }
    } 
    //1.将某区间每一个数乘上x
	//2.将某区间每一个数加上x
	//3.求出某区间每一个数的和
}
int lowbit(int x)//树状数组2 
{
    return x&-x;
}
void add(int x,int k)
{
    while(x<=n)
    {
        tree[x]+=k;
        x+=lowbit(x);
    }
}
int find(int x)
{
    int ans=0;
    while(x!=0)
    {
        ans+=tree[x];
        x-=lowbit(x);
    }
    return ans;
}
int szsz2()
{
	n=read(),m=read();
    for(int i=1;i<=n;i++)s[i]=read();
    for(int i=1;i<=m;i++)
    {
        x=read();
        if(x==1)
        {
            a=read(),b=read(),c=read();
            add(a,c);
            add(b+1,-c);
        }
        else 
        {
        	a=read();
            cout<<s[a]+find(a)<<endl;
        }
    }
	//1.将某区间每一个数数加上x
	//2.求出某一个数
}
int main()
{
	cout<<"说起来,幸福本身就是因人而异的"<<"\n";
	cout<<"\n";
	cout<<"有些人认为只要能混口饭吃就行了"<<"\n";
	cout<<"有些人只要有书读就能满足"<<"\n";
	cout<<"有些人认为只有全力地生存才是最重要的"<<"\n";
	cout<<"有些人只要得到克服某种目标的瞬间就能满足"<<"\n";
	cout<<"有些人只要某个人得到幸福,自己就会跟着幸福"<<"\n";
	cout<<"也有些人则令人伤透脑筋地刚好相反"<<"\n";
	cout<<"\n";
	cout<<"但是,大部分人都没有觉悟"<<"\n";
	cout<<"他们不知道究竟什么能给自己带来幸福"<<"\n";
	cout<<"但是,他们会异口同声地表示想要获得幸福"<<"\n";
	cout<<"那样的人即使能察觉到幸福"<<"\n";
	cout<<"也没办法变得幸福"<<"\n";
	cout<<"\n"; 
	cout<<"最重要的是要敢于正视自己的内心"<<"\n";
	cout<<"\n";
	cout<<"抱歉"<<"\n";
	cout<<"我已经..."<<"\n";
	cout<<"绝对不可能再获得幸福了"<<"\n";
	cout<<"\n";
	cout<<"因为..."<<"\n";
	cout<<"我发现了..."<<"\n";
	cout<<"其实我..."<<"\n";
	cout<<"早就已经被幸福包围了"<<"\n";
	cout<<"长存不灭的过去_逐渐消失的未来"; 
    return 0;
}

愿这世界对你温柔以待!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值