- 按位贪心有的
的没有下界,于是令表示到,合法的最小段数
#include<bits/stdc++.h>
#define cs const
using namespace std;
cs int N = 2e3 + 50;
typedef long long ll;
int n, A, B, a[N]; ll Sum;
namespace FSY{
cs int N = 105;
bool dp[N][N];
bool chk(ll now, int t){
memset(dp,0,sizeof(dp)); dp[0][0]=true;
for(int i=1; i<=n; i++)
for(int j=1; j<=i&&j<=B; j++)
for(ll k=i,x=0; k; k--){
x+=(ll)a[k];
if((x & ((1ll<<t)+now-1)) != x) continue;
dp[i][j]|=dp[k-1][j-1];
} for(int i=A; i<=B; i++) if(dp[n][i]) return true;
return false;
}
void work(){
int k=0; while(Sum) Sum>>=1,++k; ll now=0;
for(int i=k-1;~i;i--) if(!chk(now,i)) now|=1ll<<i;
cout<<now;
}
}
namespace Yolanda{
int dp[N];
bool chk(ll now, int t){
memset(dp,0x3f,sizeof(dp)); dp[0]=0;
for(int i=1; i<=n; i++)
for(ll j=i,x=0; j; j--){
x+=(ll)a[j]; if((x & ((1ll<<t)+now-1)) != x) continue;
dp[i]=min(dp[i],dp[j-1]+1);
} return dp[n]<=B;
}
void work(){
int k=0; while(Sum) Sum>>=1,++k; ll now=0;
for(int i=k-1;~i;i--) if(!chk(now,i)) now|=1ll<<i;
cout<<now;
}
}
int main(){
#ifdef FSYolanda
freopen("1.in","r",stdin);
#endif
scanf("%d%d%d",&n,&A,&B);
for(int i=1; i<=n; i++) scanf("%d",&a[i]), Sum+=(ll)a[i];
if(n<=100) return FSY::work(),0;
else return Yolanda::work(),0;
}
- 暴力建边是,分析一下发现是的,即长度的边每次最多条,本质不同的的边最多条,每个点可以新转移的边的长度是原本的集合和这步之前到达的长度的集合,集合的总大小和边集大小是一样的,用或判重 可以做到
#include<bits/stdc++.h>
#define cs const
#define pb push_back
using namespace std;
typedef pair<int, int> pi;
cs int N = 3e4 + 50;
int n, m, b[N], p[N], mx;
vector<int> G[N]; bitset<N> ok[N];
struct node{ int a, b, d; };
queue<node> q; bool vs[N];
void trans(int v, int dt, int d){
if(!vs[v]){
for(int t : G[v]) if(!ok[v][t])
ok[v][t]=true, q.push({v,t,d}); vs[v]=true;
} if(!ok[v][dt]) ok[v][dt]=true, q.push({v,dt,d});
}
int main(){
#ifdef FSYolanda
freopen("1.in","r",stdin);
#endif
scanf("%d%d",&n,&m); int S=0,T=0;
for(int i=1; i<=m; i++){
scanf("%d%d",&b[i],&p[i]);
if(i==1) S=b[i]; if(i==2) T=b[i];
G[b[i]].pb(p[i]); mx=max(mx,p[i]);
} for(int t : G[S]) q.push({S,t,0}), ok[S][t]=true; vs[S]=true;
while(!q.empty()){
node x = q.front(); q.pop();
int u=x.a, dt=x.b; if(u==T) return cout<<x.d,0;
if(u-dt>=0) trans(u-dt,dt,x.d+1);
if(u+dt<n) trans(u+dt,dt,x.d+1);
} puts("-1"); return 0;
}
- 按中点排序,存在一个分解点左边的走左边的桥右边的走右边的桥,用数据结构维护中位数即可
#include<bits/stdc++.h>
#define cs const
#define pb push_back
using namespace std;
namespace IO{
cs int Rlen=1<<22|1;
inline char gc(){
static char buf[Rlen],*p1,*p2;
(p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin));
return p1==p2?EOF:*p1++;
}
int read(){
int x=0; char c=gc(); bool f=false;
while(!isdigit(c)) f=c=='-', c=gc();
while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^48), c=gc();
return f?-x:x;
} int op(){
char c=gc(); while(isspace(c)) c=gc();
return c=='A'?0:1;
}
} using namespace IO;
typedef long long ll;
cs ll INF = 1e18;
cs int N = 1e5 + 50;
int K, n, S[N], T[N], bin[N<<1], sz; ll Ans;
namespace zkw{
cs int M = 1<<18;
int sz[M<<1]; ll sm[M<<1];
void clr(){ memset(sz,0,sizeof(sz)); memset(sm,0,sizeof(sm)); }
void add(int x, ll v){ for(x+=M;x;x>>=1) ++sz[x],sm[x]+=v; }
ll query(){
int k=sz[1]>>1, x=1; ll as=0;
while(true){
if(x>M) break; if(k<=sz[x<<1]) x<<=1;
else k-=sz[x<<1], x=x<<1|1;
} int v=bin[x-M]; for(;x;x>>=1){
if(x&1) as+=(ll)sz[x^1]*v-sm[x^1];
else as+=(ll)sm[x^1]-(ll)sz[x^1]*v;
} return as;
}
}
int main(){
#ifdef FSYolanda
freopen("1.in","r",stdin);
#endif
K=read(), n=read(); int m=0;
for(int i=1,x,y; i<=n; i++){
x=op(); S[i]=read(); y=op(); T[i]=read();
if(x==y){ Ans+=(ll)abs(T[i]-S[i]); continue; }
bin[++sz]=S[++m]=S[i], bin[++sz]=T[m]=T[i];
} sort(bin+1,bin+sz+1); n=m;
int x=bin[(sz+1)>>1]; ll mn=0;
for(int i=1; i<=n; i++) mn+=(ll)abs(T[i]-x)+(ll)abs(S[i]-x);
if(K==1) return cout<<Ans+mn+n,0;
sz=unique(bin+1,bin+sz+1)-(bin+1);
static int id[N];
for(int i=1; i<=n; i++) id[i]=i;
sort(id+1,id+n+1,[](cs int &i, cs int &j){
return S[i]+T[i] < S[j]+T[j];
}); static ll pr[N], sf[N];
for(int i=1,x,y,u; i<=n; i++){
u=id[i];
x=lower_bound(bin+1,bin+sz+1,S[u])-bin;
y=lower_bound(bin+1,bin+sz+1,T[u])-bin;
zkw::add(x,S[u]); zkw::add(y,T[u]); pr[i]=zkw::query();
} zkw::clr();
for(int i=n,x,y,u; i>=1; i--){
u=id[i];
x=lower_bound(bin+1,bin+sz+1,S[u])-bin;
y=lower_bound(bin+1,bin+sz+1,T[u])-bin;
zkw::add(x,S[u]); zkw::add(y,T[u]);
sf[i]=zkw::query(); mn=min(mn,pr[i]+sf[i+1]);
} cout<<Ans+mn+n; return 0;
}