比赛过题:ADEFGJ
补题:BCH
A
签到
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL qpow(LL x,LL n)
{
LL ret=1;
for(;n;n>>=1)
{
if(n&1) ret=ret*x;
x=x*x;
}
return ret;
}
LL a[25];
void init()
{
for(int i=1;i<=20;i++)
a[i]=qpow(i,i);
}
int main()
{
init();
LL n;
while(cin>>n)
{
LL ans=upper_bound(a,a+16,n)-a-1;
cout<<ans<<endl;
}
}
B
动态开点线段树+剪枝
#include<bits/stdc++.h>
using namespace std;
const int H=1e6,N=150000*30,INF=1e9+7;
int root[57],mn[N],ls[N],rs[N],tot,X;
bool ok;
int newnode()
{
mn[++tot]=INF;
ls[tot]=rs[tot]=0;
return tot;
}
void update(int &rt,int l,int r,int p,int val)
{
if(!rt) rt=newnode();
mn[rt]=min(mn[rt],val);
if(l==r) return ;
int m=(l+r)>>1;
if(p<=m) update(ls[rt],l,m,p,val);
else update(rs[rt],m+1,r,p,val);
}
void query(int rt,int l,int r,int ql,int qr)
{
if(ok) return;
if((ql<=l&&qr>=r)||(ls[rt]==0&&rs[rt]==0))
{
if(mn[rt]<=X) ok=true;
return ;
}
int m=(l+r)>>1;
if(ql<=m&&ls[rt]) query(ls[rt],l,m,ql,qr);
if(qr>m&&rs[rt]) query(rs[rt],m+1,r,ql,qr);
}
int main()
{
int op;
tot=0;
for(int i=0;i<=50;++i) root[i]=newnode();
while(~scanf("%d",&op))
{
if(op==3) break;
if(op==0)
{
tot=0;
for(int i=0;i<=50;++i) root[i]=newnode();
}
if(op==1)
{
int x,y,c;
scanf("%d%d%d",&x,&y,&c);
update(root[c],1,H,y,x);
}
else if(op==2)
{
int x,y1,y2,ans=0;
scanf("%d%d%d",&x,&y1,&y2);
X=x;
for(int i=0;i<=50;++i)
{
ok=false;
query(root[i],1,H,y1,y2);
ans+=ok;
}
printf("%d\n",ans);
}
}
return 0;
}
C
三元环
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
namespace IO {
const int MX = 2e7; //1e7占用内存11000kb
char buf[MX]; int c, sz;
void begin() {
c = 0;
sz = fread(buf, 1, MX, stdin);
}
inline bool read(int &t) {
while(c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++;
if(c >= sz) return false;
bool flag = 0; if(buf[c] == '-') flag = 1, c++;
for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++) t = t * 10 + buf[c] - '0';
if(flag) t = -t;
return true;
}
}
const int N=1e5+3;
int n,m;
vector<int> adj[N];
LL ans;
map<pair<int,int>,int> mp;
int d[N];
int link[N];
int l[2*N],r[2*N];
void init()
{
ans=0;
mp.clear();
for(int i=1;i<=n;i++)
adj[i].clear(),d[i]=0,link[i]=0;
}
pair<int,int> Union(int u,int v)
{
return make_pair(min(u,v),max(u,v));
}
void add(int u1,int u2,int u3)
{
mp[Union(u1,u2)]++;
mp[Union(u3,u2)]++;
mp[Union(u1,u3)]++;
}
void solve()
{
for(int i=0;i<m;i++)
{
int u=l[i],v=r[i];
for(int x:adj[u])
link[x]=u;
for(int x:adj[v])
if(link[x]==u) add(u,v,x);
}
for(map<pair<int,int>,int>::iterator it=mp.begin();it!=mp.end();++it)
{
int t=it->second;
ans+=t*(t-1)/2;
}
}
int main()
{
// freopen("test.in","r",stdin);
IO::begin();
// while(~scanf("%d%d",&n,&m))
while(IO::read(n))
{
IO::read(m);
init();
for(int i=0;i<m;i++)
{
IO::read(l[i]),d[l[i]]++;
IO::read(r[i]),d[r[i]]++;
}
for(int i=0;i<m;i++)
{
if(d[l[i]]>d[r[i]]||d[l[i]]==d[r[i]]&&l[i]>r[i])
swap(l[i],r[i]);
adj[l[i]].push_back(r[i]);
}
solve();
printf("%lld\n",ans);
}
}
D
4*n骨牌覆盖
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=16;
const int mod=1000000007;
LL b[N]={1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
LL hh[N][N]=
{
{1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1},
{0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0},
{1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
{0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0},
{0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0},
{1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0},
{1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
};
struct Mat
{
LL mat[16][16];
LL* operator[] (int x)
{
return mat[x];
}
}A[65];
Mat Mut(Mat a,Mat b)
{
Mat c;
memset(c.mat,0,sizeof(c.mat));
for(int i=0;i<N;i++)
for(int k=0;k<N;k++) if(a[i][k])
for(int j=0;j<N;j++)
{
c[i][j]+=a[i][k]*b[k][j];
c[i][j]%=mod;
}
return c;
}
void init_A()
{
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
A[0][i][j]=hh[i][j];
for(int i=1;i<64;i++)
A[i]=Mut(A[i-1],A[i-1]);
}
LL cal(LL n)
{
LL b_[N];
memcpy(b_,b,sizeof(b));
for(int p=0;n;n>>=1)
{
if(n&1)
{
LL temp[N]={0};
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
temp[i]=(temp[i]+A[p][i][j]*b_[j])%mod;
memcpy(b_,temp,sizeof(b_));
}
p++;
}
return b_[0];
}
int main()
{
init_A();
LL n;
// n=(1LL<<60)-1;
// int T=5000;
// while(T--)
// cal(n);
while(~scanf("%lld",&n))
printf("%lld\n",cal(n));
}
E
水题
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=100005;
ll n,a[N],b0[30],b1[30],X,q;
ll AND(ll p){
ll ans=0;
for(ll i=0;i<30;++i){
if(((a[p]>>i)%2==0&&b0[i]==1)||b0[i]==0){
ans+=(1<<i);
}
}
return ans;
}
ll OR(ll p){
ll ans=0;
for(ll i=0;i<30;++i){
if(b1[i]==0)continue;
if((a[p]>>i)%2==1&&b1[i]==1)continue;
ans+=(1<<i);
}
return ans;
}
ll XOR(ll p){
return X^a[p];
}
int main(void){
while(~scanf("%I64d%I64d",&n,&q)){
memset(b0,0,sizeof(b0));
memset(b1,0,sizeof(b1));
X=0;
for(ll i=0;i<n;++i){
scanf("%I64d",&a[i]);
X^=a[i];
for(ll j=0;j<30;++j){
if((a[i]>>j)&1)b1[j]++;
else b0[j]++;
}
}
while(q--){
ll p;
scanf("%I64d",&p);p--;
printf("%I64d %I64d %I64d\n",AND(p),OR(p),XOR(p));
}
}
}
F
最小生成树
#include <queue>
#include <cstdio>
#include <set>
using namespace std;
const int N=200005;
int n,m,pre[N];
set<int>s;
struct node{
int w,u,v;
node(int U,int V,int W){
w=W;u=U;v=V;
}
friend bool operator<(node a,node b){
return a.w>b.w;
}
};
void init(int n){
for(int i=0;i<=n;++i)
pre[i]=i;
}
int Find(int x){
return pre[x]==x?x:pre[x]=Find(pre[x]);
}
void Union(int x,int y){
int a=Find(x),b=Find(y);
if(a!=b)pre[a]=b;
}
priority_queue<node>q;
int main(void){
while(~scanf("%d%d",&n,&m)){
init(n);
while(!q.empty())q.pop();
s.clear();
for(int i=0;i<n;++i){
int x,y;
scanf("%d%d",&x,&y);
}
for(int i=0;i<m;++i){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
q.push(node(u,v,-w));
Union(u,v);
}
int p=-1;
for(int i=1;i<=n;++i){
if(p==-1)p=Find(i);
s.insert(Find(i));
}
for(set<int>::iterator it=s.begin();it!=s.end();++it){
if(p!=*it)q.push(node(p,*it,0));
}
init(n);
int ans1=0,ans2=0;
while(!q.empty()){
node t=q.top();q.pop();
int u=t.u,v=t.v,w=t.w;
if(Find(u)!=Find(v)){
Union(u,v);
}else{
ans1++;
ans2-=w;
}
}
printf("%d %d\n",ans1,ans2);
}
}
G
贪心+dp
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=1000005;
int n,a[N],t,dp[N][3];
int Max(int a,int b){
return a>b?a:b;
}
int solve(int p,int res){
if(p>n)return 0;
if(dp[p][res]!=-1)return dp[p][res];
int ans=0;
if(res==2)ans=Max(ans,solve(p+1,a[p+1])+1);
if(res==1&&p+2<=n&&a[p+1]>=1&&a[p+2]>=1)ans=Max(ans,solve(p+2,a[p+2]-1)+1);
ans=Max(ans,solve(p+1,a[p+1]));
return dp[p][res]=ans;
}
int main(void){
while(~scanf("%d",&n)){
memset(a,0,sizeof(a));
memset(dp,-1,sizeof(dp));
for(int i=0;i<n;++i){
scanf("%d",&t);
a[t]++;
}
int ans=0;
for(int i=1;i<=n;++i){
if(a[i]>2){
t=a[i]-1;
ans+=t/2;
a[i]=1+t%2;
}
}
ans+=solve(1,a[1]);
printf("%d\n",ans);
}
}
H
数论
#include <cstdio>
using namespace std;
typedef long long ll;
ll n,a,m;
ll powmod(ll a,ll n){
ll r=1;
while(n){
if(n&1)r=r*a%m;
a=a*a%m;;
n>>=1;
}
return r;
}
int main(void){
while(~scanf("%I64d%I64d",&n,&a)){
if(n==0)printf("1\n");
else if(a&1)printf("1\n");
else{
m=1<<n;
ll ans=0;
for(ll b=1;b<n;++b)
if(powmod(a,b)==powmod(b,a))
ans++;
for(ll i=1;i<=n;++i)
if(a*i>=n){
ans+=m/(1<<i)-(n-1)/(1<<i);
break;
}
printf("%I64d\n",ans);
}
}
}
J
可持久化Trie
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int a[N],root[N],s[N*35][2],c[N*35],tot,sz[N],id[N],ord;
vector<int> adj[N];
void update(int &rt,int last,int x,int d)
{
rt=++tot;
s[rt][0]=s[last][0];
s[rt][1]=s[last][1];
c[rt]=c[last]+1;
if(d==-1) return ;
int b=(x>>d)&1;
if(b^1) update(s[rt][0],s[last][0],x,d-1);
else update(s[rt][1],s[last][1],x,d-1);
}
void dfs(int u,int p)
{
id[u]=++ord;
sz[u]=1;
update(root[ord],root[ord-1],a[u],29);
for(int v : adj[u])
{
if(v==p) continue;
dfs(v,u);
sz[u]+=sz[v];
}
}
int query(int rt1,int rt2,int x,int d,int res)
{
if(d==-1) return res;
int b=((x>>d)&1)^1;
int val=c[s[rt2][b]]-c[s[rt1][b]];
if(val) return query(s[rt1][b],s[rt2][b],x,d-1,res|(1<<d));
else return query(s[rt1][b^1],s[rt2][b^1],x,d-1,res);
}
int main()
{
int n,q;
while(~scanf("%d%d",&n,&q))
{
for(int i=1;i<=n;++i) adj[i].clear();
memset(s,0,sizeof(s));
memset(c,0,sizeof(c));
ord=tot=0;
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int u=2;u<=n;++u)
{
int v;
scanf("%d",&v);
adj[v].push_back(u);
}
dfs(1,0);
while(q--)
{
int x,y;
scanf("%d%d",&y,&x);
printf("%d\n",query(root[id[y]-1],root[id[y]+sz[y]-1],x,29,0));
}
}
return 0;
}