常见题型模板汇总

前排提醒:超大类(如图论)请使用单'#',单个知识点大类(如Nim)请使用2个'#'号标题,小类(如Nim变式)使用3个'#'标题 、标明复杂度并加粗,其余请按格式编写

杂项

朝鲜大哥快读

朝鲜大哥快读:
#define FI(n) FastIO::read(n)
#define FO(n) FastIO::write(n)
#define Flush FastIO::Fflush()
//程序末尾写上   Flush;
namespace FastIO
{
    const int SIZE = 1 << 16;
    char buf[SIZE], obuf[SIZE], str[60];
    int bi = SIZE, bn = SIZE, opt;
    double D[] = {0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, 0.00000001, 0.000000001, 0.0000000001};
    int read(char *s)
    {
        while (bn)
        {
            for (; bi < bn && buf[bi] <= ' '; bi++)
                ;
            if (bi < bn)
                break;
            bn = fread(buf, 1, SIZE, stdin);
            bi = 0;
        }
        int sn = 0;
        while (bn)
        {
            for (; bi < bn && buf[bi] > ' '; bi++)
                s[sn++] = buf[bi];
            if (bi < bn)
                break;
            bn = fread(buf, 1, SIZE, stdin);
            bi = 0;
        }
        s[sn] = 0;
        return sn;
    }
    bool read(int &x)
    {
        int n = read(str), bf = 0;
        if (!n)
            return 0;
        int i = 0;
        if (str[i] == '-')
            bf = 1, i++;
        else if (str[i] == '+')
            i++;
        for (x = 0; i < n; i++)
            x = x * 10 + str[i] - '0';
        if (bf)
            x = -x;
        return 1;
    }
    bool read(long long &x)
    {
        int n = read(str), bf;
        if (!n)
            return 0;
        int i = 0;
        if (str[i] == '-')
            bf = -1, i++;
        else
            bf = 1;
        for (x = 0; i < n; i++)
            x = x * 10 + str[i] - '0';
        if (bf < 0)
            x = -x;
        return 1;
    }
    void write(int x)
    {
        if (x == 0)
            obuf[opt++] = '0';
        else
        {
            if (x < 0)
                obuf[opt++] = '-', x = -x;
            int sn = 0;
            while (x)
                str[sn++] = x % 10 + '0', x /= 10;
            for (int i = sn - 1; i >= 0; i--)
                obuf[opt++] = str[i];
        }
        if (opt >= (SIZE >> 1))
        {
            fwrite(obuf, 1, opt, stdout);
            opt = 0;
        }
    }
    void write(long long x)
    {
        if (x == 0)
            obuf[opt++] = '0';
        else
        {
            if (x < 0)
                obuf[opt++] = '-', x = -x;
            int sn = 0;
            while (x)
                str[sn++] = x % 10 + '0', x /= 10;
            for (int i = sn - 1; i >= 0; i--)
                obuf[opt++] = str[i];
        }
        if (opt >= (SIZE >> 1))
        {
            fwrite(obuf, 1, opt, stdout);
            opt = 0;
        }
    }
    void write(unsigned long long x)
    {
        if (x == 0)
            obuf[opt++] = '0';
        else
        {
            int sn = 0;
            while (x)
                str[sn++] = x % 10 + '0', x /= 10;
            for (int i = sn - 1; i >= 0; i--)
                obuf[opt++] = str[i];
        }
        if (opt >= (SIZE >> 1))
        {
            fwrite(obuf, 1, opt, stdout);
            opt = 0;
        }
    }
    void write(char x)
    {
        obuf[opt++] = x;
        if (opt >= (SIZE >> 1))
        {
            fwrite(obuf, 1, opt, stdout);
            opt = 0;
        }
    }
    void Fflush()
    {
        if (opt)
            fwrite(obuf, 1, opt, stdout);
        opt = 0;
    }
}; // namespace FastIO

博弈

Nim游戏汇总

xy限制

复杂度:\(O(n)\)
nim博弈+限制条件(一个人不能取x,一个人不能取y)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N],t,n,x,y,cnt,sum;
int main(){
    scanf("%d",&t);
    while(t--){
        cnt=sum=0; 
        scanf("%d%d%d",&n,&x,&y);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            if(a[i]>=min(x,y)) cnt++;
        }
        if(x==y){
            for(int i=1;i<=n;i++){
                sum^=a[i]/(2*x)*x+a[i]%x;
            }
        }
        else if(!cnt){
            for(int i=1;i<=n;i++){
                sum^=a[i];
            }
        }
        else if(x<y&&cnt>=2){
            sum=0;
        }
        else if(x<y&&cnt==1){
            for(int i=1;i<=n;i++){
                if(a[i]<x) sum^=a[i];
            }
            int mx=*max_element(a+1,a+n+1);
            if(mx>sum&&sum<x&&mx-sum!=x) sum=1;
            else sum=0;
        }
        else if(x>y){
            sum=1;
        }
        if(sum) printf("Jslj\n");
        else printf("yygqPenguin\n");
    } 
}

数据结构

求逆序对

复杂度:\(O(nlogn)\)

const int maxn=1e6+6;
int a[maxn],r[maxn],n;
ll ans=0;
void msort(int s,int t){
	if(s==t) return ;
	int mid=s+t>>1;
	msort(s,mid),msort(mid+1,t);
	int i=s,j=mid+1,k=s;
	while(i<=mid&&j<=t)
		if(a[i]<=a[j]) r[k++]=a[i++];
		else r[k++]=a[j++],ans+=(ll)mid-i+1;
	while(i<=mid) r[k]=a[i],k++,i++;
	while(j<=t) r[k]=a[j],k++,j++;
	for(int i=s;i<=t;i++) a[i]=r[i]; 
}
inline int read(){
	char ch=getchar();
	int x=0,f=1;
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
	return x*f;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) a[i]=read();
	msort(1,n);
	printf("%lld\n",ans);
	return 0;
}
posted @ 2021-08-17 11:36  ZJUT3  阅读(37)  评论(0)    收藏  举报