练练思维补题

补题:

1710A - Color the Picture

赛后t了,在判断完数量的时候,如果是奇数那么就必须有某一个颜色能贡献出不少于3行/列,才能使得答案正确。

#include <bits/stdc++.h>

using namespace std;
const int N=2e6+10;

long long a[N];
int sum;
void solve()
{
    long long n,m,k;cin>>n>>m>>k;
    long long cnt1=0,cnt2=0,maxx1=0,maxx2=0;

    for(int i=1;i<=k;i++)
    {
        cin>>a[i];
        if(a[i]/m>1)cnt1+=a[i]/m,maxx1=max(maxx1,a[i]/m);
        if(a[i]/n>1)cnt2+=a[i]/n,maxx2=max(maxx2,a[i]/n);
    }
    if(n%2==0&&cnt1>=n){ puts("YES");return;}
    else if(m%2==0&&cnt2>=m) { puts("YES");return;}
    if((n&1)&&maxx1>=3&&cnt1>=n) puts("YES");
    else if((m&1)&&maxx2>=3&&cnt2>=m) puts("YES");
    else puts("NO");


}

int main(){
    int t;
    cin>>t;
    while(t--)solve();
}

Guess the Cycle Size

每次随意猜i到1和1到i,如果得到-1表明是i-1,否则继续把i变大猜,因为题目保证随机,所以必定会出现两个不同的答案。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+10;

long long a[N];
int q(int x,int y) {
    cout<<"?"<<' '<<x<<' '<<y<<endl;
    int xx;
    cin>>xx;
    return xx;
}
void solve() {
    for(int i=4;;i++){
        int t1,t2;
        t1=q(1,i);
        t2=q(i,1);
        if(t1==-1){
            cout<<"! "<<i-1<<endl;
            return;
        }
        if(t1!=t2){
            cout<<"! "<<t1+t2<<endl;
            return;
        }
    }

}

signed main() {
    int t=1;
   // cin>>t;
    while(t--)
        solve();
}

Kirei and the Linear Function

因为每次计算的lr都是定值,只需预处理哈希值,然后都放桶里取最小即可。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+10;
char s[N];
int ss[N];
int p[N];
int len,w,q;
vector<int> cnt[10];
void init() {
    cin>>s+1;
    len=strlen(s+1);
    cin>>w>>q;
    p[0]=1;
    for(int i=0;i<10;i++) cnt[i].clear();
    for(int i=1; i<=len; i++) {
        p[i]=p[i-1]*10%9;
    }
    for(int i=1; i<=len; i++) {
        ss[i]=ss[i-1]*10+s[i]-'0';
        ss[i]%=9;
    }
    for(int l=1,r=l+w-1;r<=len;l++,r++){
        int c=(ss[r]-ss[l-1]*p[r-l]%9+9)%9;
        cnt[c].push_back(l);
    }

}

void solve() {
    init();
    while(q--){
        int l,r,k;
        cin>>l>>r>>k;
        int t=(ss[r]-ss[l-1]*p[r-l]%9+9)%9;
        pair<int,int> res={1000000000,1000000000};
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                if((t*i+j)%9==k&&cnt[i].size()&&cnt[j].size()){
                    if(i==j&&cnt[i].size()>=2) res=min(res,{cnt[i][0],cnt[i][1]});
                    else if(i!=j) res=min(res,{cnt[i][0],cnt[j][0]});
                }
            }
        }
        if(res.first==1000000000&&res.second==1000000000) cout<<-1<<' '<<-1<<'\n';
        else cout<<res.first<<' '<<res.second<<'\n';

    }

}

signed main() {
    ios::sync_with_stdio(0),cin.tie(0);
    int t=1;
    cin>>t;
    while(t--)
        solve();
}


E - New School

#include<bits/stdc++.h>
using namespace std;

struct Node{
    int l,r;
    int minn;
}tr[200100*4];
int sum[200100];
vector<int> stu[200100];
long long tsum[200100];
void pushup(Node &u,Node &l,Node &r)
{
   u.minn=min(l.minn,r.minn);
}
void pushup(int u)
{
    pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}

void build(int u,int l,int r)
{
    if(l==r)tr[u]={l,r,sum[l]};
    else{
        tr[u]={l,r};
        int mid=l+r>>1;
        build(u<<1,l,mid);
        build(u<<1|1,mid+1,r);
        pushup(u);
    }
}

Node query(int u,int l,int r)
{
    if(tr[u].l>=l&&tr[u].r<=r) return tr[u];
    else{
        int mid=tr[u].l+tr[u].r>>1;
        if(r<=mid) return query(u<<1,l,r);
        else if(l>mid) return query(u<<1|1,l,r);
        else{
            Node left=query(u<<1,l,r);
            Node right=query(u<<1|1,l,r);
            Node res;
            pushup(res,left,right);
            return res;
        }
    }
}

void solve()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=110000;i++) sum[i]=0,tsum[i]=0;
    
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        sum[x]++;
    }
    for(int i=1;i<=m;i++)
    {
        stu[i].clear();
        int kk;
        scanf("%d",&kk);
        for(int j=1;j<=kk;j++)
        {
            int x;
            scanf("%d",&x);
            stu[i].push_back(x);
            tsum[i]+=x;
        }
        sum[((tsum[i]+kk-1)/kk)]--;
    }
    for(int i=110000;i;i--)
    {
        sum[i]+=sum[i+1];
       // cout<<sum[i]<<' ';
    }
    build(1,1,110000);
    
    for(int i=1;i<=m;i++)
    {
        int kk=stu[i].size();
        for(int j=0;j<kk;j++)
        {
            int last=(tsum[i]+kk-1)/kk;
            int now=(tsum[i]-stu[i][j]+kk-2)/(kk-1);
            if(last==now){
                if(query(1,1,110000).minn>=0) cout<<1;
                else cout<<0;
            }
            else if(last<now){
                bool ok=1;
                if(query(1,last+1,now).minn<1) ok=0;
                if(now<=110000&&query(1,now,110000).minn<0) ok=0;
                if(1<=last&&query(1,1,last).minn<0) ok=0;
                if(ok) cout<<1;
                else if(!ok) cout<<0;
            }
            else{
                bool ok=1;
                if(1<=now&&query(1,1,now).minn<0) ok=0;
                if(query(1,now+1,last).minn<-1) ok=0;
                if(last+1<=110000&&query(1,last+1,110000).minn<0) ok=0;
                if(ok) cout<<1;
                else if(!ok) cout<<0;
            }
        }
    }
    cout<<endl;
    
    
}
int main()
{
    int t;
    cin>>t;
    while(t--) solve();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值