2022.4.17 省選vp記
阿新 • • 發佈:2022-04-17
前言
去年沒有打 NOIP,所以今年自然沒法打省選,就 vp 一下了。
Day 1
T1 前處理器
本題思路:
Hash+字串+模擬
除了程式碼有些長,然後樣例比較迷惑之後
這道題就是細節。難度好像不大
我第一遍的時候被 空串
給卡掉了。這是第二遍程式碼:
#include<bits/stdc++.h> #define int long long #define rint register int #define ull unsigned long long #define pii pair<int,int> #define fir first #define sec second #define rep(i,a,b) for(int i=a;i<=b;++i) #define Down(i,a,b) for(int i=a;i>=b;--i) using namespace std; using PII = pair<int,int>; typedef long long ll; const int N=110; const int Mod=19260817; const ull Bas=13331; int n,dcnt; struct Hash_Table{ struct edge{int pre,nxt,val;ull to;}e[N*N]; int head[Mod],ecnt; void insert(ull x,int id){ e[++ecnt]={0,head[x%Mod],id,x},e[head[x%Mod]].pre=ecnt,head[x%Mod]=ecnt; } void erase(ull x){ for(rint i=head[x%Mod];i;i=e[i].nxt){ if(e[i].to==x){ int pr=e[i].pre,nx=e[i].nxt; if(pr) e[pr].nxt=nx; e[nx].pre=pr,e[i].to=e[i].val=e[i].pre=e[i].nxt=0; return ; } } } int query(ull x){ for(rint i=head[x%Mod];i;i=e[i].nxt){ if(e[i].to==x) return e[i].val; } return -1; } }mp; template<typename T>inline void ckmax(T &x,T y){x=x>y?x:y;} template<typename T>inline void ckmin(T &x,T y){x=x<y?x:y;} string val[N];bool vis[N]; namespace IO{ ull get_hs(string s){ ull res=0; for(int i=0;i<s.length();++i) res=res*Bas+s[i]; return res; } bool imp(char x){ if(isalpha(x)) return 1; if(isdigit(x)) return 1; return x=='_'; } void solve(string s){ int len=s.length(); for(int i=0;i<len;++i){ int j=i; string tmp; while(j<len&&imp(s[j])) tmp+=s[j++]; ull cur=get_hs(tmp),id=mp.query(cur); if(id!=-1&&!vis[id]){ vis[id]=1; solve(val[id]); vis[id]=0; }else{ cout<<tmp; } if(j<len) putchar(s[j]); i=j; } return ; } } using namespace IO; namespace Fast{ inline int read(){ int t=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') t=10*t+(c^48),c=getchar(); return t; } inline void write(int x){ if(x<10){ putchar(x|48); return; } write(x/10); putchar((x%10)|48); }} using namespace Fast; signed main(void){ //freopen(".in","r",stdin); //freopen(".out","w",stdout); n=read(); while(n--){ string str; getline(cin,str); int len=str.length(); if(str[0]=='#'){ if(str[1]=='d'){ string s1; int pter=8; while(str[pter]!=' ') s1+=str[pter++]; mp.insert(get_hs(s1),++dcnt); ++pter; for(int j=pter;j<len;++j) val[dcnt]+=str[j]; }else{ string s; for(int j=7;j<len;++j) s+=str[j]; ull cur=get_hs(s); mp.erase(cur); } puts(""); }else{ solve(str); putchar('\n'); } } return 0; //fclose(stdin); //fclose(stdout); }
T2 填樹
沒有什麼好的思路
目前已知最優解是那個 樹形DP+數學,顯然我不會。。。。
所以只能暴搜了
#include<iostream> #include<iomanip> #include<queue> #include<stack> #include<set> #include<algorithm> #include<bitset> #include<string> #include<vector> #include<iosfwd> #include<cmath> #include<complex> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #define rint register int using namespace std; using PII = pair<int,int>; #define ll long long #define inf 4557430888798830399 using namespace std; namespace Fast{ inline int read(){ int t=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') t=10*t+(c^48),c=getchar(); return t; } inline void write(int x){ if(x<10){ putchar(x|48); return; } write(x/10); putchar((x%10)|48); }} using namespace Fast; const ll mod=1000000007,inf = 0x3f3f3f3f3f,N=210,M=N*2; ll n,k,l[N],r[N],h[N],e[M],ne[M],idx,f[N][50][50],g[N][50][50]; ll qmi(ll a,ll b,ll p){ ll res=1; while(b){ if(b&1) res=res*a%p; a=a*a%p; b>>=1; } return res; } void adds(ll a,ll b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } void dfs(ll u,ll fa){ for(ll i=h[u];~i;i=ne[i]){ ll v=e[i]; if(v==fa) continue; for(ll j=1;j<=500;j++){ for(ll k1=j;k1<=min(500ll,k1+k);k1++){ for(ll p=l[v];p<=r[v];p++){ ll t1=min(j,p),t2=max(k1,p); f[v][t1][t2]=(f[v][t1][t2]+f[u][j][k1])%mod; } } } for(ll j=1;j<=500;j++){ for(ll k1=j;k1<=min(500ll,k1+k);k1++){ for(ll p=l[v];p<=r[v];p++){ ll t1=min(j,p),t2=max(k1,p); g[v][t1][t2]=((g[v][t1][t2]+g[u][j][k1])%mod+f[u][j][k1]*p%mod)%mod; } } } dfs(v,u); } } int main(){ memset(h,-1,sizeof h); n=read(),k=read(); for(ll i=1;i<=n;i++){ scanf("%lld%lld",&l[i],&r[i]); } for(ll i=1;i<n;i++){ ll x,y; scanf("%lld%lld",&x,&y); adds(x,y),adds(y,x); } ll cnt=0,sum=0; ll a1=0,b1=0; for(ll root=1;root<=n;root++){ ll cnt1=0,cnt2=0,sum1=0,sum2=0; memset(f,0,sizeof f); memset(g,0,sizeof g); cnt2+=r[root]-l[root]+1; for(ll i=l[root];i<=r[root];i++){ f[root][i][i]=1; g[root][i][i]=i; sum2=(sum2+i)%mod; } dfs(root,-1); for(ll i=1;i<=n;i++){ for(ll j=1;j<=500;j++){ for(ll p=j;p<=min(500ll,j+k);p++){ cnt1=(cnt1+f[i][j][p])%mod,sum1=(sum1+g[i][j][p])%mod; } } } cnt1=(cnt1-cnt2+mod)%mod; sum1=(sum1-sum2+mod)%mod; a1=(a1+cnt1)%mod; b1=(b1+sum1)%mod; cnt=(cnt+cnt2)%mod; sum=(sum+sum2)%mod; } ll iv2=qmi(2,mod-2,mod); cnt=(cnt+a1*iv2%mod)%mod; sum=(sum+b1*iv2%mod)%mod; printf("%lld\n",cnt); printf("%lld",sum); return 0; }
T3 學術社群
一個網路流題,但是我現在寫個網路流模板都還費勁兒,這個題自然就不會了
暴力也只會打一個數據點的。
#include<iostream> #include<iomanip> #include<queue> #include<stack> #include<set> #include<algorithm> #include<bitset> #include<string> #include<vector> #include<iosfwd> #include<cmath> #include<complex> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #define int long long #define rint register int using namespace std; using PII = pair<int,int>; typedef long long ll; using namespace std; #define pb push_back const int N=8e4,M=3e5+5; int n,m,cnt=0; string nam[N],s[M][4]; map <string, int> mp; vector <int> ls[N];vector <int> lx[N]; vector <int> id[N];vector <int> ans; bool vis[M]; int main() { int T; read(T); while(T--){ cin>>n>>m; mp.clear(); for(int i=1;i<=n;i++) cin>>nam[i],mp[nam[i]] = i, ls[i].clear(), lx[i].clear(), id[i].clear(); queue <int> que; memset(vis, 0, sizeof(vis)); for(int i = 1; i <= m; i++){ cin>>s[i][1]>>s[i][2] >> s[i][3]; if(s[i][3]=="loushang" && mp.find(s[i][2]) != mp.end()) ls[mp[s[i][2]]].pb(i); else if(s[i][3] == "louxia" && mp.find(s[i][2]) != mp.end()) lx[mp[s[i][2]]].pb(i); else que.push(i), vis[i] = 1; id[mp[s[i][1]]].pb(i); } cnt = 0; ans.clear(); while(!que.empty()){ int k = que.front(); que.pop(); int u = mp[s[k][1]]; bool flag = 0; ans.pb(k); for(auto it : lx[u]){ if(vis[it]) continue; vis[it] = 1;que.push(it); flag = 1;cnt++; break; } if(flag) continue; for(auto it : ls[u]){ if(vis[it]) continue; vis[it]=1,que.push(it); cnt++; break; } } cout<<cnt<<endl; for(auto it : ans) cout<<it<<endl; for(int i = 1; i <= m; i++) if(!vis[i]) cout<<i<<" "; putchar('\n'); void(); } return 0; }