zoukankan      html  css  js  c++  java
  • Tokitsukaze and Duel CodeForces

    大意: 给定01串, 两人轮流操作, Tokitsukaze先手. 每次操作可以选择长为$k$的区间, 全部替换为$0$或$1$, 若替换后同色则赢. 求最后结果.

    先判断第一步是否能直接赢, 不能的话若所有后继都是必败则必败, 否则平局.

    正确性很显然, 因为一次操作不能直接赢的话, 只要模仿对手操作一定能平局.

    那么问题就转化为判断一步操作后是否能赢.

    假设$0$的最大范围为$[L[0],R[0]]$,$1$的最大范围为$[L[1],R[1]]$, 那么只要操作前$R[0]-L[0]+1le k$或$R[1]-L[1]+1le k$那么一定必胜.

    然后用带撤销的线段树枚举所有后继模拟即可.

    #include <iostream>
    #include <cstdio>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    #define lc (o<<1)
    #define rc (lc|1)
    #define mid ((l+r)>>1)
    #define ls lc,l,mid
    #define rs rc,mid+1,r
    using namespace std;
    
    const int N = 1e6+10;
    int n,k,clk,tim[N<<2];
    char s[N];
    struct _ {
    	int L[2],R[2];
    	void upd(int v, int l, int r) {
    		L[v]=l,R[v]=r;
    		L[!v]=1e9,R[!v]=-1e9;
    	}
    	_ operator + (const _ & rhs) const { 
    		_ ret;
    		REP(i,0,1) { 
    			ret.L[i]=min(L[i],rhs.L[i]);
    			ret.R[i]=max(R[i],rhs.R[i]);
    		}
    		return ret;
    	}
    } tr[N<<2],tmp[N<<2];
    
    void build(int o, int l, int r) {
    	if (l==r) return tmp[o].upd(s[l]=='1',l,r);
    	build(ls),build(rs);
    	tmp[o]=tmp[lc]+tmp[rc];
    }
    void upd(int o) {
    	if (tim[o]!=clk) tr[o]=tmp[o],tim[o]=clk;
    }
    void update(int o, int l, int r, int ql, int qr, int v) {
    	upd(o);
    	if (ql<=l&&r<=qr) return tr[o].upd(v,l,r);
    	else { 
    		upd(lc),upd(rc);
    		if (mid>=ql) update(ls,ql,qr,v);
    		if (mid<qr) update(rs,ql,qr,v);
    		tr[o]=tr[lc]+tr[rc];
    	}
    }
    int chk() {
    	REP(i,0,1) if (tr[1].R[i]-tr[1].L[i]+1<=k) return 1;
    	return 0;
    }
    
    int work() {
    	scanf("%d%d%s", &n, &k, s+1);
    	build(1,1,n);
    	++clk,upd(1);
    	if (chk()) return 1;
    	int cnt = 0;
    	REP(i,1,n-k+1) {
    		int f = 0;
    		++clk, update(1,1,n,i,i+k-1,1), f += chk();
    		++clk, update(1,1,n,i,i+k-1,0), f += chk();
    		if (f==2) ++cnt;
    	}
    	return cnt==n-k+1?0:-1;
    }
    
    int main() {
    	int t = work();
    	if (t==1) puts("tokitsukaze");
    	else if (t==-1) puts("once again");
    	else puts("quailty");
    }
    
  • 相关阅读:
    grep使用多个查询条件--或
    Qt Quick App的两种启动模式
    ICP编程软件配置(烧写KEIL编译后的bin文件)
    C/C++语言中const的用法
    QT小插件类之QRoundProgressBar
    QT实现单个EXE文件
    QT小技巧学习记录
    无线路由器的五种工作模式
    Qt5.4静态编译方法
    Altium Designer极坐标布局方法
  • 原文地址:https://www.cnblogs.com/uid001/p/11183349.html
Copyright © 2011-2022 走看看