摘要
1月14/15号就是ICPC香港站了,考完期末考试回学校复习,准备知乎上刷刷专题,做几套abc和arc
abc283e dp
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N][2][2][2];// i-1 i i+1
int n,m,a[N][N];
int check(int i,int x,int y,int z){
for(int j=1;j<=m;j++){
int X=a[i][j]^x;
int Y=a[i-1][j]^y;
int Z=a[i+1][j]^z;
if(i-1==0)Y=100;
if(i+1==n+1)Z=100;
if(X==Y||X==Z)continue;
if(j==1&&a[i][j]!=a[i][j+1])return 0;
if(j==m&&a[i][j]!=a[i][j-1])return 0;
if(j>1&&j<m&&a[i][j]!=a[i][j-1]&&a[i][j]!=a[i][j+1])return 0;
}
return 1;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j];
for(int j=1;j<=m;j++)a[0][j]=a[n+1][j]=2;
memset(f,0x3f,sizeof f);
for(int i=1;i<=n;i++){
for(int x=0;x<=1;x++){
for(int y=0;y<=1;y++){
for(int z=0;z<=1;z++){
if(check(i,x,y,z)){
if(i> 1)f[i][x][y][z]=min(f[i-1][y][0][x],f[i-1][y][1][x])+z;
if(i==1)f[i][x][y][z]=x+y+z;
}
}
}
}
}
int ans=0x3f3f3f3f;
for(int x=0;x<=1;x++)for(int y=0;y<=1;y++)ans=min(ans,f[n][x][y][0]);
if(ans==0x3f3f3f3f)ans=-1;
cout<<ans;
}
abc283f 线段树
#include<bits/stdc++.h>
#define ls u<<1
#define rs u<<1|1
using namespace std;
const int N=2e5+10;
int n,v[N],a[N*4],b[N*4],c[N*4],d[N*4];
void pushup(int u){
a[u]=min(a[ls],a[rs]);
b[u]=min(b[ls],b[rs]);
c[u]=min(c[ls],c[rs]);
d[u]=min(d[ls],d[rs]);
}
void ins(int t,int u,int x,int val,int l=1,int r=n){
if(l==r){
if(t==1)a[u]=val;
if(t==2)b[u]=val;
if(t==3)c[u]=val;
if(t==4)d[u]=val;
return;
}
int mid=l+r>>1;
if(x<=mid)ins(t,ls,x,val,l,mid);
else ins(t,rs,x,val,mid+1,r);
pushup(u);
}
int query(int t,int u,int ql,int qr,int l=1,int r=n){
if(l>qr||r<ql)return 1e9;
if(ql<=l&&r<=qr){
if(t==1)return a[u];
if(t==2)return b[u];
if(t==3)return c[u];
if(t==4)return d[u];
}
int mid=l+r>>1;
return min(query(t,ls,ql,qr,l,mid),query(t,rs,ql,qr,mid+1,r));
}
int ans[N];
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
memset(a,0x3f,sizeof a);
memset(b,0x3f,sizeof b);
memset(c,0x3f,sizeof c);
memset(d,0x3f,sizeof d);
for(int i=1;i<=n;i++)cin>>v[i];
memset(ans,0x3f,sizeof ans);
for(int i=1;i<=n;i++){
int &x=ans[i];
x=min(x,i+v[i]+query(1,1,1,v[i]-1));ins(1,1,v[i],-i-v[i]);
x=min(x,i-v[i]+query(2,1,v[i]+1,n));ins(2,1,v[i],-i+v[i]);
}
for(int i=n;i>=1;i--){
int &x=ans[i];
x=min(x,-i+v[i]+query(3,1,1,v[i]-1));ins(3,1,v[i],i-v[i]);
x=min(x,-i-v[i]+query(4,1,v[i]+1,n));ins(4,1,v[i],i+v[i]);
}
for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
}
abc283g 线性基
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
int d[61],tot;
int n,L,R;
//构造序列的线性基
void insert(ll x)
{
for(int i=60;i>=0;i--)
{
if(x&(1ll<<i))//注意,如果i大于31,前面的1的后面一定要加ll
{
if(d[i])x^=d[i];
else
{
d[i]=x;
tot++;
break;//插入成功就退出
}
}
}
}
//求最大值
ll ans()
{
ll anss=0;
for(int i=60;i>=0;i--)//记得从线性基的最高位开始
if((anss^d[i])>anss)anss^=d[i];
return anss;
}
//求最小值
ll query_min()
{
for (int i=0;i<=60;i++)
if (d[i])
return d[i];
return 0;
}
//求第k小值
void work()//处理线性基
{
for(int i=1;i<=60;i++)
for(int j=1;j<=i;j++)
if(d[i]&(1ll<<(j-1)))d[i]^=d[j-1];
}
ll k_th(ll k)
{
if(k==1)return 0;
//特判一下,假如k=1,并且原来的序列可以异或出0,就要返回0,tot表示线性基中的元素个数,n表示序列长度
k--;//类似上面,去掉0的情况,因为线性基中只能异或出不为0的解
// work();
if(k>(1ll<<tot))return -1;//最多只有2的tot次方种异或情况
ll ans=0;
for(int i=0;i<=60;i++)
if(d[i]!=0)
{
if(k%2==1)ans^=d[i];
k/=2;
}
return ans;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>L>>R;
for(int i=1,x;i<=n;i++)cin>>x,insert(x);
work();
for(int i=L;i<=R;i++)cout<<k_th(i)<<" ";
}
线段树
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
#define ls u<<1
#define rs u<<1|1
int s[N*4],lz[N*4],a[N*4],b[N*4],c[N*4];
int n,q,l,r;
void pushup(int u){
a[u]=min(a[ls],a[rs]);
s[u]=s[ls]+s[rs];
}
void pushdown(int u){
if(lz[u]){
a[ls]+=lz[u];
lz[ls]+=lz[u];
a[rs]+=lz[u];
lz[rs]+=lz[u];
lz[u]=0;
}
}
void build(int u,int l=1,int r=n){
lz[u]=s[u]=0;
if(l==r){
a[u]=b[l];
return;
}
int mid=l+r>>1;
build(ls,l,mid);build(rs,mid+1,r);
pushup(u);
}
void update(int u,int ql,int qr,int l=1,int r=n){
if(ql>r||qr<l)return;
if(ql<=l&&r<=qr){
if(a[u]>1){
a[u]--,lz[u]--;return;}
else if(l==r){
s[u]++,a[u]=b[l];return;}
}
pushdown(u);
int mid=l+r>>1;
update(ls,ql,qr,l,mid);
update(rs,ql,qr,mid+1,r);
pushup(u);
}
int query(int u,int ql,int qr,int l=1,int r=n){
if(ql>r||qr<l)return 0;
if(ql<=l&&r<=qr)return s[u];
int mid=l+r>>1;
pushdown(u);
return query(ls,ql,qr,l,mid)+query(rs,ql,qr,mid+1,r);
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
while(cin>>n>>q){
for(int i=1;i<=n;i++)cin>>b[i];
build(1);
while(q--){
string op;
cin>>op>>l>>r;
if(op[0]=='a')update(1,l,r);
else cout<<query(1,l,r)<<'\n';
}
}
}
abc285h类欧几里得
#include<bits/stdc++.h>
#define ll unsigned long long
#define ull ll
using namespace std;
// sum{i=0}^{n-1} floor((a*i+b)/c)
ull f(ull a,ull b,ull c,ull n){
ull ret=0;
ret+=b/c*n;b%=c;
ret+=a/c*n*(n-1)/2;a%=c;
if(a*n+b<c)return ret;
return ret+f(c,(a*n+b)%c,a,(a*n+b)/c);
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int T;
cin>>T;
while(T--){
int n,m,r;
cin>>n>>m>>r;
ll ans=0;
n=(n-r)/m+1;
for(int k=0;k<30;k++){
ans+=f(m,r+(1ll<<k),1ll<<k+1,n)-f(m,r,1ll<<k+1,n);
}
cout<<ans<<'\n';
}
}
abc282e
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=550;
int n,m,p[N],a[N];
struct node{
int a,b,w;
bool operator<(const node&t)const{
return w>t.w;
}
};
int find(int x){
if(p[x]==x)return x;
return p[x]=find(p[x]);
}
int qpow(int a,int b){
int ans=1;
while(b){
if(b&1)ans=ans*a%m;
b/=2;
a=a*a%m;
}
return ans;
}
int cal(int i,int j){
return (qpow(a[i],a[j])+qpow(a[j],a[i]) )%m;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
vector<node>v;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++){
v.push_back({
i,j,cal(i,j)});
}
}
for(int i=1;i<=n;i++)p[i]=i;
sort(v.begin(),v.end());
int ans=0;
for(auto [a,b,c]:v){
if(find(a)==find(b))continue;
p[find(a)]=find(b);
ans+=c;
}
cout<<ans;
}
abc282f
#include<bits/stdc++.h>
using namespace std;
int n,m,q;
const int N=1e5+10;
int f[N][21];
int L[N],R[N];
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
for(int j=0;i+(1<<j)-1<=n;j++){
f[i][j]=++m;
L[m]=i;
R[m]=i+(1<<j)-1;
}
}
cout<<m<<'\n';
for(int i=1;i<=m;i++)cout<<L[i]<<" "<<R[i]<<'\n';
cout.flush();
cin>>q;
while(q--){
int l,r;
cin>>l>>r;
int k=__lg(r-l+1);
int L1=l,R1=l+(1<<k)-1;
int R2=r,L2=r-(1<<k)+1;
cout<<f[L1][k]<<" "<<f[L2][k]<<'\n';
cout.flush();
}
}