(AtCoder Beginner Contest 268) D-E

D - Unique Username

显然搜索 我们枚举全排列的同时枚举额外'_'的个数
但是注意的是我们要恢复现场 但是s显然不能-=
那我们用一个tmp变量即可

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"Yes"<<endl;
#define NO cout<<"No"<<endl;
#define _ 0
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
map<string,int>mp;
int n,m,sum;
string S[N];
bool vis[N];
void dfs(int now,int sz,string s){
    if(now==n+1){
        if(s.size()<3||s.size()>16)return;
        else if(!mp[s]){
            cout<<s<<endl;
            exit(0);
        }
    }else{
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                vis[i]=1;
                string tmp=s;
                tmp+=S[i];
                if(now==n)dfs(now+1,sz,tmp);
                else {
                    tmp+='_';dfs(now+1,sz,tmp);
                    for(int j=1;j<=sum-sz;j++){
                        tmp+='_';
                        dfs(now+1,sz+j,tmp);
                    }
                }
                vis[i]=0;
            }
        }
    }
}
void solve() {
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>S[i];sum+=S[i].size();
    }
    sum=17-n-sum;
    for(int i=1;i<=m;i++){
        string s;cin>>s;
        mp[s]++;
    }
    dfs(1,0,"");
    cout<<-1<<endl;
}
signed main(){
    fast
    int T;T=1;
    while(T--) {
        solve();
    }
    return ~~(0^_^0);
}

E - Chinese Restaurant (Three-Star Version)

我们不难发现我们原来的n2做法是不可能了
但是我们可以画一个坐标轴
容易发现的是我们一共就只有x长 然后当我们距离该点总是先增后减 或者先减后增的
我们可以在坐标轴上画几根 发现只有两种情况的方程 那就是n/2作为分界线
那我们相当于有n条这样的方程 我们累加起来即可
但是这里有人就要问了 两个方程咋加阿 我们可以发现这些个方程都很特殊 斜率都是为1的 那我们这样直接将k b加起来显然正确的
但是这里是仅仅是区间修改 那我们直接差分即可 不需要线段树
最后值得注意的是我们add的(l,r) 要注意下标 我们可以拿n为奇数的情况模拟一下 就知道了 中间那段一定是闭区间

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"Yes"<<endl;
#define NO cout<<"No"<<endl;
#define _ 0
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int k[N],b[N],a[N],pos[N],n;
void add(int l,int r,int kk,int bb){
    if(l>r)return;
    k[l]+=kk,b[l]+=bb;
    k[r+1]-=kk,b[r+1]-=bb;
}
void add(int v){
    if(v<n/2){
        add(0,v-1,-1,v);
        add(v,v+n/2,1,-v);
        add(v+n/2+1,n-1,-1,n+v);
    }else{
        add(0,v-n/2-1,1,n-v);
        add(v-n/2,v,-1,v);
        add(v+1,n-1,1,-v);
    }
}
void solve(){
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i],pos[a[i]]=i;
    for(int i=0;i<n;i++){
        int v=(pos[i]-i+n)%n;
        add(v);
    }
    for(int i=0;i<n;i++)k[i]+=k[i-1],b[i]+=b[i-1];
    int ans=INF;
    for(int i=0;i<n;i++)ans=min(ans,k[i]*i+b[i]);
    cout<<ans<<endl;
}
signed main(){
    fast
    int T;T=1;
    while(T--) {
        solve();
    }
    return ~~(0^_^0);
}
posted @ 2022-09-16 14:07  ycllz  阅读(77)  评论(0)    收藏  举报