DAY 3

Morning

预计得分:100+50+30

实际得分:100 +0+ 0

T1 某博弈论(骗分)水题

做法

1.n&1&&m&1先手败

2.我的智障做法

#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;

void read(int &s){
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar());
    for(s=0;isdigit(ch);s=s*10+ch-'0',ch=getchar());
}

int sg[1005][1005];

int mex(int i,int j,int k){
    if(i!=0&j!=0&&k!=0)return 0;
    for(int l=1;l<=max(max(i,j),k);++l)
        if(l!=j&&l!=k&&l!=i)return l;
    return max(max(i,j),k)+1;
}

int main(){
	freopen("star.in","r",stdin);
	freopen("star.out","w",stdout);
    int n,m;
    sg[0][0]=1;
    sg[1][0]=0;
    sg[0][1]=0;
    for(int i=0;i<=1000;++i)
		for(int j=0;j<=1000;++j){
        if(i!=0||j!=0){
            sg[i][j]=mex(sg[i-1][j-1],sg[i-1][j],sg[i][j-1]);
            sg[i][j+1]=mex(sg[i][j],sg[i-1][j],sg[i-1][j+1]);
            sg[i+1][j]=mex(sg[i][j],sg[i][j-1],sg[i+1][j-1]);
        }
	}
    while(scanf("%d%d",&n,&m)==2){
        if(!n&&!m)break;
        if(!sg[n][m])printf("Chito
");
        else printf("Yuri
");
    }
    return 0;
}

递推求SG函数
然后过了
其实我这个代码改一改就能A很多博弈论问题
他们的n*m%2只能骗骗分了
(自我安慰)

T3

煞笔线段树
根本没时间写
时间全部浪费在T1那个煞笔题目上了
T1花了我一个半小时以上啊



Afternoon

预计得分:20+100+30-60

实际得分:0 +100+10

暴力从来没写成功过……23333333
我第三题怎么得的10分???
我那个暴力N遍DFS根本写错了
按理说是爆零啊
事实证明我写暴力只是在浪费时间
自始至终写的暴力几乎没有得过分
得分不如rand()

T1

考虑把边一条一条加进去(用并查集)
一个联通块中,有大于等于2个环时无解
有一个环时,答案就是2(环上有两种分边方式)
当为一个树时,方案数是点的个数(每个点都可以当成根)

T2

煞笔做法骗80分
找到原因啦
因为我写的是递归求解
在把递归语句搁在特判里面了
23333333333

#include<iostream>
#include<cstdio>
#define N 1000005
using namespace std;

long long ans;
long long n,k;
int sum=-1;
int wei[N];
long long pos[N];

int as(int l,int r){
    int er=0;
    for(int i=l;i<=r;++i)
        if(i%2==0)er++;
    return er;
}

void work(int num){
    for(int i=num;i>=num;--i){
        if(i%2&&wei[i]){
            //ans+=wei[i]*as(0,i);
            ans+=pos[as(0,i-1)];
            return;
        }
        if(i%2==0&&wei[i]){
            ans+=wei[i]*pos[as(0,i-1)];
        }
        work(num-1);
//这数据也太水了吧,犯这种错误都能得80分
    }
}

int main(){
//    freopen("endless.in","r",stdin);
//    freopen("endless.out","w",stdout);
    cin>>n>>k;
    while(n){
        wei[++sum]=n%k;n/=k;}
    pos[0]=1;
    for(int i=1;i<=sum;++i)pos[i]=pos[i-1]*k;
/*    int nnn=wei[sum];
    long long asd=1;
    for(int i=0;i<sum;++i){
        if(i%2==0)asd*=k;
    }
    if(sum%2==0)asd*=nnn;
    ans+=asd;
*/
    work(sum);
    cout<<ans;
    return 0;
}

T3

线段树维护煞笔贪心
区间求最大值、区间修改
因为每个点最多被置为0一次
所以复杂度O(nlog(n))

另一种做法
链剖,根据权值和划分轻重链,然后排序一个一个加

总之

总而言之时间不太够
所以这么几场考试都只做一个正解
时间不够啦

原文地址:https://www.cnblogs.com/qdscwyy/p/7755989.html