(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);
}