冲刺省选2月17日 (互测)
作者:互联网
T1 最短路
需要一个数据结构实现快速加一个 2 的幂和比较大小
考虑主席树维护二进制数,每个节点维护答案和第一个为 0 的位置
加 \(2^k\) 就从 k 往后找到第一个为 0 的位置改成 1,中间的位改为 0
比较大小线段树上二分就行了
T2 集合
要求一个集合 S ,满足 \(\prod_{i\in S}i!\) 为完全平方数
删的个数 <=3
若 n 为偶数,\(2^{\frac{n}{2}}\frac{n}{2}!\prod_{i=1}^{\frac{n}{2}}(2k-1)!^2\)
若 n/2 为偶数,只删 \(\frac{n}{2}!\) ,否则再删个 2!
若 n 为奇数,把 n 删了就是偶数了,所以 <=3
(但是实际上这个并不是最优策略)
所以依次判断 n ,n-1
判断 n-2 就每个质数随机赋权,然后用个 unordered_map 存异或和判断
剩下的就是 n-3 ,删 n,n/2, 2
(打表,发现 4|n 则答案是 n-1,然后把不是 4|n 的减到 4|n,就 65 了)
T3
只会 dp ,统一取模卡常能拿 35
然而我滚动数组最后没调出来,顺便 \(k=1\) 的也错了,剩 10 分
代码
T1
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define il inline
#define li tre[i].lc
#define lj tre[j].lc
#define ri tre[i].rc
#define rj tre[j].rc
const int N=2e5+20,M=2e5+20;
const int mod=1e9+7;
bool jud[N];
int n,m,s,t;
int tot,d[N];
int first[N],cnt;
int mi[N],sum[N];
struct tree{
bool jd;
int loc,ans;
int lc,rc;
bool lazy;
}tre[(int)(1.1e7)];
void pushdown(int i,int l,int r){
if(l==r)return;
tre[++tot]=tre[li];li=tot;
tre[++tot]=tre[ri];ri=tot;
tre[li].loc=l,tre[ri].loc=((l+r)>>1)+1;
tre[li].jd=tre[ri].jd=tre[li].ans=tre[ri].ans=0;
tre[li].lazy=tre[ri].lazy=1;
tre[i].lazy=0;
}
bool cmp(int i,int j,int l,int r,bool jd1,bool jd2){
if(!jd1&&!jd2)return 0;
if(l==r)return jd1*tre[i].jd<jd2*tre[j].jd;
int mid=(l+r)>>1;
if((!tre[i].lazy)*jd1*tre[ri].ans!=(!tre[j].lazy)*jd2*tre[rj].ans)
return cmp(ri,rj,mid+1,r,jd1&(!tre[i].lazy),jd2&(!tre[j].lazy));
else return cmp(li,lj,l,mid,jd1&(!tre[i].lazy),jd2&(!tre[j].lazy));
}
struct qxxx{
int v,next,w;qxxx(){}
qxxx(int v_,int next_,int w_){v=v_,next=next_,w=w_;}
}cc[2*N];
struct val_{
int x,id;val_(){}
val_(int x_,int id_){x=x_,id=id_;}
friend bool operator<(val_ a,val_ b){
return !cmp(a.id,b.id,1,M,1,1);
}
};
priority_queue<val_>dui;
il int min_(int x,int y){return x>y?y:x;}
il void qxx(int u,int v,int w){
cc[++cnt]=(qxxx){v,first[u],w};
first[u]=cnt;
}
il int read(){
int s=0;char ch=getchar();
while(ch>'9'||ch<'0')ch=getchar();
while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
return s;
}
void update(int i){
tre[i].jd=tre[li].jd&tre[ri].jd;
tre[i].ans=(tre[li].ans+tre[ri].ans)%mod;
tre[i].loc=min_(tre[li].loc,tre[ri].loc);
}
void chg(int &i,int l,int r,int L,int R,bool jd){
if(L>R)return;
tre[++tot]=tre[i],i=tot;
if(tre[i].lazy)pushdown(i,l,r);
if(l>=L&&r<=R){
tre[i].jd=jd;
tre[i].ans=jd*(sum[r]-sum[l-1]+mod)%mod;
tre[i].loc=jd?M:l;
tre[i].lazy=!jd;
return;
}int mid=(l+r)>>1;
if(L<=mid)chg(tre[i].lc,l,mid,L,R,jd);
if(R>mid)chg(tre[i].rc,mid+1,r,L,R,jd);
update(i);
}
int qry(int &i,int l,int r,int L,int R){
if(tre[i].lazy)pushdown(i,l,r);
if(l>=L&&r<=R)return tre[i].loc;
int mid=(l+r)>>1,ans=M;
if(L<=mid)ans=min_(ans,qry(tre[i].lc,l,mid,L,R));
if(R>mid)ans=min_(ans,qry(tre[i].rc,mid+1,r,L,R));
return ans;
}
void build(int &i,int &j,int l,int r){
i=++tot;j=++tot;if(l==r){
tre[i]=(tree){l==M,l,l==M?mi[M-1]*2%mod:0};
tre[j]=(tree){0,l,0};
return;
}int mid=(l+r)>>1;
build(tre[i].lc,tre[j].lc,l,mid);
build(tre[i].rc,tre[j].rc,mid+1,r);
update(i);update(j);
}
void dij(){
build(d[0],d[s],1,M);
for(int i=1;i<=n;++i)if(s!=i)d[i]=d[0];
int x,now,k,sl;dui.push(val_(s,d[s]));
while(dui.size()){
x=dui.top().x;dui.pop();
if(jud[x])continue;jud[x]=1;
for(int v,i=first[x];i;i=cc[i].next){
v=cc[i].v;now=d[x];
k=qry(now,1,M,cc[i].w,M);sl=tot;
chg(now,1,M,k,k,1),chg(now,1,M,cc[i].w,k-1,0);
if(!cmp(d[v],now,1,M,1,1))dui.push(val_(v,d[v]=now));
else tot=sl;
}
}
}
signed main(){
freopen("hellagur.in","r",stdin),freopen("hellagur.out","w",stdout);
mi[0]=sum[0]=1;
for(int i=1;i<N;++i){
mi[i]=mi[i-1]*2%mod;
sum[i]=(sum[i-1]+mi[i])%mod;
}n=read(),m=read();
for(int x,y,z,i=1;i<=m;++i){
x=read(),y=read(),z=read();
qxx(x,y,z);qxx(y,x,z);
}s=read(),t=read();if(s==t){cout<<0<<endl;return 0;}
dij();printf("%d\n",d[t]!=1?tre[d[t]].ans:-1);
}
T2
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define int long long
#define pr pair<int,bool>
#define fi first
#define se second
#define mkp make_pair
#define ull unsigned long long
const int N=1e6+11;
const ull mod=998244353;
bool fp[N];
int n;
ull mi[N],val[N];
int p[N],num;
vector<pr>vct[N];
namespace ans1{
bool now[25];
vector<int>sta,ans;
bool vt[25][25];
void solve(){
for(int i=2;i<=n;++i){
memcpy(vt[i],vt[i-1],sizeof(vt[i]));
for(pr x : vct[i])vt[i][x.fi]^=x.se;
}
for(int jd,i=1;i<(1<<n);++i){
memset(now,0,sizeof(now));sta.clear();
for(int j=1;j<=n;++j)if((1<<j-1)&i){
sta.push_back(j);
for(int k=1;p[k]<=n;++k)now[p[k]]^=vt[j][p[k]];
}jd=1;for(int j=1;j<=n;++j)jd&=(now[j]==0);
if(sta.size()<=ans.size()||!jd)continue;
swap(ans,sta);
}cout<<ans.size()<<endl;for(int v : ans)cout<<v<<" ";cout<<endl;
}
};
namespace ans2{
ull hs;
ull sum[N];
unordered_map<ull,vector<int> >mp;
void solve(){
for(int i=(n&1)+2;i<=n;i+=2)hs^=val[i];
if(!hs){cout<<n<<endl;for(int i=1;i<=n;++i)cout<<i<<" ";cout<<endl;return;}
for(int i=2;i<=n;++i)sum[i]=val[i]^sum[i-1],mp[sum[i]].push_back(i);
for(int i=2;i<=n;++i){
if(hs==sum[i]){
cout<<n-1<<endl;
for(int j=1;j<i;++j)cout<<j<<" ";
for(int j=i+1;j<=n;++j)cout<<j<<" ";
cout<<endl;return;
}
}
for(int i=2;i<=n;++i){
ull k=hs^sum[i];
if(mp.find(k)!=mp.end()){
for(int v : mp[k])if(v!=i){
cout<<n-2<<endl;
for(int j=1;j<=n;++j)if(j!=v&&j!=i)cout<<j<<" ";
cout<<endl;return;
}
}
}cout<<n-3<<endl;
for(int i=1;i<=n;++i)if(i!=2&&i!=n&&i!=n/2)cout<<i<<" ";cout<<endl;
}
};
void pre(){
uniform_int_distribution<unsigned long long> range(1,~(0llu));
default_random_engine e(rand());
fp[0]=fp[1]=1;
for(int i=2;i<N;++i){
if(!fp[i])p[++num]=i,vct[i].push_back(mkp(i,1)),val[i]=range(e);
for(int tmp,j=1;j<=num&&p[j]*i<N;++j){
fp[tmp=i*p[j]]=1;vct[tmp]=vct[i];
val[tmp]=val[i]^val[p[j]];
if(i%p[j]==0){vct[tmp][vct[tmp].size()-1].se^=1;break;}
else vct[tmp].push_back(mkp(p[j],1));
}
}
}
signed main(){
freopen("mountain.in","r",stdin),freopen("mountain.out","w",stdout);
pre();cin>>n;
for(int i=mi[0]=1;i<N;++i)mi[i]=mi[i-1]*mod;
if(n<=20)ans1::solve();else ans2::solve();
}
标签:lazy,17,省选,tre,int,bool,ans,define,互测 来源: https://www.cnblogs.com/sitiy/p/15906248.html