C. Tokitsukaze and Discard Items

题意:Codeforces Round #573 (Div. 2)_i++

给定一个1-n的序列  将其分成多份每份k个数  有m个特殊数字(预先给出) 每次可以删除最左边的包含特殊数字的那份 的所有特殊数字  这为一次操作  该操作后后面的数字均前移    问多少次操作能删除所有的特殊数字

 

比赛的时候做了半天  强行模拟即可

Codeforces Round #573 (Div. 2)_#define_02Codeforces Round #573 (Div. 2)_c++_03
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
#define lson l,m,pos<<1
#define rson m+1,r,pos<<1|1
typedef pair<int,int>pii;
//////////////////////////////////
const int N=1e5+5;
 
ll n,k,m;
ll a[N],ans=0;
int main()
{
    cin>>n>>m>>k;
 
    rep(i,1,m)scanf("%lld",&a[i]);
 
    int pos=1;ll now=0,d=0,cnt;//now 表示前面删除了多少个数字
 
    while(pos<=m)
    {
        cnt=(a[pos]-now-1)/k;d=0;
        while( (a[pos]-now-1)/k==cnt &&pos<=m)
        {
            pos++;d++;
        }
        ans++;
        now+=d;
    }
    cout<<ans;
 
    return 0;
}
View Code

 

D. Tokitsukaze, CSL and Stone Game

题意:有多堆石头   每堆有ai个石头

每次没人可以选择一个非空堆取一个石头    

如果没石头可以取  或者取完以后存在两堆石头个数一样  那么就输了

 

大体的思想是    很显然   大的数不可能越过比他小的数(也就是不可能别的比他小的数小)   所以最后肯定是0-n-1的阶梯排序

还要特判一下其他特殊情况就行了

Codeforces Round #573 (Div. 2)_#define_02Codeforces Round #573 (Div. 2)_c++_03
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
#define lson l,m,pos<<1
#define rson m+1,r,pos<<1|1
typedef pair<int,int>pii;
//////////////////////////////////
const int N=1e5+5;
 
int n;
ll a[N];
map<int,int>mp;
 
int main()
{
    RI(n);
    rep(i,1,n)
    scanf("%d",&a[i]);
 
    sort(a+1,a+1+n);
    ll cnt=0;
 
    int ok=1;
    rep(i,1,n)
    {
        mp[a[i]]++;
        if(mp[a[i]]>2)return puts("cslnb"),0;
        if(mp[a[i]]==2)
        {
            if(ok)ok=0;
            else return puts("cslnb"),0;
        }
    }
    if(a[1]==a[2]&&a[1]==0)return puts("cslnb"),0;
 
    rep(i,1,n)
    if(mp[a[i]]==2&&mp[a[i]-1])return puts("cslnb"),0;
 
    rep(i,1,n)
    cnt+=a[i]-i+1;
 
    if(cnt%2==0)
        printf("cslnb");
    else printf("sjfnb");
 
    return 0;
}
 
 
 
 
 
 
View Code

 

 

E

题意:有长度为n的01序列  每次可以选择连续的k段  将其改成0或1  如果某人将序列修改成全部一样 那么就赢了  如果没有结果 输出once again

如果先手的人第一次取不能赢  他就不可能赢了  (因为另一个人不傻  为了保证自己不输甚至可以将第一个取的操作反向一下  就可以拖住了)

如果第一个人无论怎么取  第二个人取的时候都能赢  那么第二个人赢  (因为第一个人当知道自己不可能赢的时候 肯定想法设法阻挠第二个人赢  当无论怎么取第二人都赢的时候就没辙了)

剩下就是 没有结果了

 

Codeforces Round #573 (Div. 2)_#define_02Codeforces Round #573 (Div. 2)_c++_03
//#pragma comment(linker, "/STACK:102400000,102400000") 
#include "bits/stdc++.h"
#define pb push_back
#define ls l,m,now<<1
#define rs m+1,r,now<<1|1
#define hhh printf("hhh\n")
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
using namespace std;
typedef long long ll;
typedef pair<int,int> pr;
inline int read() {
    int x=0;
    char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0', c=getchar();
    return x;
}
 
const int maxn = 2e5+10;
const int mod = 1e9+7;
const double eps = 1e-9;
 
int n, k;
string l;
 
int main() {
    //ios::sync_with_stdio(false);
    n=read(), k=read();
    cin>>l;
    int l1=1, l2=1;
    for(int i=1; i<n&&l[i]==l[i-1]; ++i, ++l1);
    for(int i=n-2; i>=0&&l[i]==l[i+1]; --i, ++l2);
    if(l1>=n-k||l2>=n-k||(l1+l2>=n-k&&l[0]==l[n-1])) printf("tokitsukaze");
    else if(l1==n-k-1&&l2==n-k-1&&l[0]!=l[n-1]&&k>=(n+1)/2) printf("quailty");
    else printf("once again");
}
E1
Codeforces Round #573 (Div. 2)_#define_02Codeforces Round #573 (Div. 2)_c++_03
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1000005;
int n,k,T;
int a[MAXN],sum[MAXN];
int q_sum(int l,int r)
{
    if(l>r)return 0;
    return sum[r]-sum[l-1];
}
bool check_fir()
{
    for(int i=1;i+k-1<=n;++i)
    {
        int lala=q_sum(1,i-1)+q_sum(i+k,n);
        if(lala==0||lala+k==n)return true;
    }
    return false;
}
bool check_sec()
{
    if(k*2<n||k==1)return false;
    int len=n-k-1;
    for(int i=2;i<=len;++i)
    {
        if(a[i]!=a[i-1]||a[n-i+1]!=a[n-i+2])return false;
    }
    if(a[len]==a[len+1]||a[n-len]==a[n-len+1]||a[1]==a[n])return false;
    return true;
}
int main()
{
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;++i)
    {
        scanf("%1d",&a[i]);
        sum[i]=sum[i-1]+a[i];
    }
    if(check_fir())
    {
        printf("tokitsukaze\n");
    }
    else
    {
        if(check_sec())
        {
            printf("quailty\n");
        }
        else
        {
            printf("once again\n");
        }
    }
    return 0;
}
E2

 

F

题意:

给定平面上的一些点  可以用U形将点包裹住  (u形任意 )  问有多少种包裹方法(包裹不同点集 算不同方法) 

首先先离散化  从最上面开始扫描  判断贡献即可 每个点往右边 和左边  判断贡献   贡献为左右区间相乘 

非常好的一题

Codeforces Round #573 (Div. 2)_#define_02Codeforces Round #573 (Div. 2)_c++_03
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s)
#define ll long long
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
#define lson l,m,pos<<1
#define rson m+1,r,pos<<1|1
typedef pair<int,int>pii;
//////////////////////////////////
const int N=2e5+5;
 
int table[N],x[N],y[N],nx,ny,n;
 
void lisan(int *x,int &nx)
{
    rep(i,1,n)table[i]=x[i];
    sort(table+1,table+1+n);
    nx=unique(table+1,table+1+n)-table;
    rep(i,1,n)
    x[i]=lower_bound(table+1,table+nx,x[i])-table;//注意加nx即可 不需要nx+1
}
 
vector<int>v[N];
 
int t[N],vis[N];
 
void add(int x)
{
    for(;x<=nx;x+=x&-x)t[x]++;
}
int qsum(int x)
{
    int ans=0;for( ;x;x-=x&-x )ans+=t[x];return ans;
}
struct node
{
    int x,y;
}s[N];
bool cmp4(node a,node b)
{
    return a.y>b.y||a.y==b.y&&a.x<b.x;
}
int main()
{
    RI(n);
    rep(i,1,n)RII(x[i],y[i]);
 
    lisan(x,nx);lisan(y,ny);
    rep(i,1,n)s[i].x=x[i],s[i].y=y[i];
 
    sort(s+1,s+1+n,cmp4);
    int k=1;ll ans=0;
    
    nx--;ny--;
    repp(i,ny,1)
    {
        for(;k<=n&&s[k].y==i;k++ )
        {
            v[i].push_back(s[k].x);
            if(!vis[s[k].x])vis[s[k].x]=1,add(s[k].x);
        }
        sort(v[i].begin(),v[i].end());
        for(int j=0;j<v[i].size();j++)
        {
            int p=0;
            if(j)p=qsum(v[i][j-1]);
            int l=qsum(v[i][j])-p;
            int r=qsum(nx)-qsum(v[i][j])+1;
            ans+=1ll*l*r;
        }
    }
    cout<<ans;
 
    return 0;
}
View Code