题解
1001 Azshara's deep sea
Unsolved.
1002 Blow up the city.
题解:倒着建图,然后将原图出度为零的点用一个新节点连接起来,支配树板题。
参考代码:
#includeusing namespace std; #define LL long long #define pb push_back //DAG图q个询问,给你u,v:去掉一个点连同和这个点相连的所有边使得u或v不能到达出度为零的点的方案 const int maxn=2e5+7; int n,m,deg[maxn],rt,a[maxn],dep[maxn],val[maxn]; int f[maxn][20]; vector<int>E[maxn],RE[maxn]; void Topsort() { queue<int>q; rt=n+1;//图可能不连通,建一个新点连接起来 for(int i=1;i<=n;i++) if(!deg[i]){q.push(i);E[rt].pb(i);RE[i].pb(rt);} int tot=0; while(!q.empty()) { int u=q.front(); q.pop(); a[++tot]=u; for(auto &v:E[u]){if((--deg[v])==0) q.push(v);} } } int LCA(int x,int y) { if(dep[x]>dep[y]) swap(x,y); for(int i=19;i>=0;i--) { if(dep[y]>dep[x]&&dep[f[y][i]]>=dep[x]) y=f[y][i]; } if(x==y) return x; for(int i=19;i>=0;i--) { if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; } return f[x][0]; } void Work() { dep[rt]=1; for(int i=1;i<=n;i++) { int u=a[i],fa=-1; for(auto &v:RE[u]) fa=(fa==-1? v:LCA(fa,v)); dep[u]=dep[fa]+1; f[u][0]=fa; for(int i=1;i<=19;i++) f[u][i]=f[f[u][i-1]][i-1]; } } int main() { int tt; scanf("%d",&tt); while(tt--) { scanf("%d%d",&n,&m); memset(f,0,sizeof(f)); for(int i=1;i<=n+1;i++) { E[i].clear(); RE[i].clear(); dep[i]=deg[i]=0; } while(m--) { int u, v; scanf("%d%d", &u, &v); E[v].pb(u); RE[u].pb(v); deg[u]++; } Topsort(); Work(); int q; scanf("%d", &q); while(q--) { int u, v; scanf("%d%d",&u,&v); int lca=LCA(u,v); printf("%d\n",dep[u]+dep[v]-dep[lca]-1); } } return 0; }
1003 Yukikaze and Demons
Unsolved.
1004 Distribution of books
https://blog.csdn.net/liufengwei1/article/details/97703075
#includeusing namespace std; #define maxl 200010 int n,tot,cnt,k; long long up,dow,ans; int a[maxl],b[maxl],dp[maxl],h[maxl],c[maxl]; long long sum[maxl]; long long num[maxl]; inline void prework() { scanf("%d%d",&n,&k); up=0;dow=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); sum[i]=sum[i-1]+a[i],num[i]=sum[i]; if(a[i]>0) up+=a[i]; else dow+=a[i]; } num[n+1]=0; sort(num+1,num+2+n); tot=unique(num+1,num+2+n)-num-1; for(int i=0;i<=n;i++) b[i]=lower_bound(num+1,num+1+tot,sum[i])-num; } inline void upd(int i,int x) { int t; while(i<=tot && i) { h[i]=c[i]; for(int k=1;k<(i&-i);k<<=1) h[i]=max(h[i],h[i-k]); i+=i&-i; } } inline int qry(int l,int r) { int ret=-n-1,len=r-l+1; while(len && r) { if(len<(r&-r)) { ret=max(ret,c[r]); r--;len--; }else { ret=max(ret,h[r]); len-=(r&-r); r-=r&-r; } } return ret; } inline bool jug(long long mid) { for(int i=1;i<=n;i++) dp[i]=0; for(int i=1;i<=tot;i++) h[i]=-n-1,c[i]=-n-1; int l=1,r=n,id,tmp; c[b[0]]=0;upd(b[0],c[b[0]]); for(int i=1;i<=n;i++) { id=lower_bound(num+1,num+1+tot,sum[i]-mid)-num; if(id>tot) continue; tmp=qry(id,tot); if(tmp<=-n-1) continue; dp[i]=max(dp[i],qry(id,tot)+1); c[b[i]]=max(c[b[i]],dp[i]); upd(b[i],c[b[i]]); if(dp[i]>=k) return true; } return false; } inline void mainwork() { long long l=dow,r=up,mid; while(l+1<r) { mid=(l+r)>>1; if(jug(mid)) r=mid; else l=mid; } if(jug(l)) ans=l; else ans=l+1; } inline void print() { printf("%lld\n",ans); } int main() { int t; scanf("%d",&t); for(int i=1;i<=t;i++) { prework(); mainwork(); print(); } return 0; }
1005 Easy Math Problem
https://blog.csdn.net/baiyifeifei/article/details/97798086
#includeusing namespace std; #define int long long const int size=2e5+5; const int mod=1e9+7; typedef long long LL; bool prime[size]; int p[size]; int tot=0; int inv6,inv2; int phi[size]; int sumiiphi[size]; int quick_pow(int a,int b) { register int ans=1; while(b) { if(b&1) ans=1LL*ans*a%mod; a=1LL*a*a%mod; b>>=1; } return ans; } int inv[205]; void init() { tot=0; phi[1]=1; for(int i=1;i true; for(int i=2;i ) { if(prime[i]) p[++tot]=i,phi[i]=i-1; for(int j=1;j<=tot&&p[j]*i ) { prime[i*p[j]]=false; if(i%p[j]==0) { phi[i*p[j]]=phi[i]*p[j]; break; } else phi[i*p[j]]=phi[i]*phi[p[j]]; } } sumiiphi[0]=0; for(int i=1;i 1]+1LL*i*i%mod*phi[i]%mod)%mod; inv6=quick_pow(6,mod-2); inv2=quick_pow(2,mod-2); inv[0]=inv[1]=1; for(int i=2;i<=200;i++) inv[i] = (mod - (mod / i)) * inv[mod % i] % mod; for (int i = 1; i <= 200; ++i)inv[i] = inv[i] * inv[i - 1] % mod; } int tol; int hk[size<<1];LL num[size<<1]; int pre[size]; int coeff[205]; void pre_lage(int k) { for(int i=1;i<=k+2;i++) coeff[i]=quick_pow(i,k); coeff[0]=0; for(int i=1;i<=k+2;i++) coeff[i]=(coeff[i-1]+coeff[i])%mod; } LL suf[205],bef[205]; int lage(int n,int k) { if(n<=k+2) return coeff[n]; bef[0] = suf[0] = 1; for (int i = 1; i <= k + 2; ++i) { bef[i] = bef[i - 1] * ((n - i) % mod) % mod; suf[i] = suf[i - 1] * ((n + i - k - 3) % mod) % mod; } LL res = 0; for (int i = 1; i <= k + 2; ++i) { LL s = coeff[i] * bef[i - 1] % mod * suf[k - i + 2] % mod * inv[i - 1] % mod * inv[k + 2 - i] % mod; if ((k + 2 - i) & 1)s = -s; res += s; res = (res % mod + mod) % mod; } return res; } int s;LL n; int id1[size],id2[size]; inline int ID(int x) { if(x<=s) return id1[x]; return id2[n/x]; } void get_h(int k) { s=sqrt(n); while(1LL*s*s<=n) s++; while(1LL*s*s>n) s--; pre[0]=0; for(register int i=1;p[i]<=s;i++) { pre[i]=(1LL*pre[i-1]+quick_pow(p[i],k+1))%mod; } tol=0; for(register LL l=1,r;l<=n;l=r+1) { r=n/(n/l); num[++tol]=r; if(r<=s) id1[r]=tol; else id2[n/r]=tol; } pre_lage(k+1); for(register int i=1;i<=tol;i++) hk[i]=(lage(num[i]%mod,k+1)-1+mod)%mod; hk[0]=0; int x=1; for(int j=1;j<=tot&&p[j]<=s;j++) { while(num[x] ; for(int i=tol;i>=x;i--) { hk[i]=((hk[i]-1LL*(pre[j]-pre[j-1]+mod)%mod*(hk[ID(num[i]/p[j])]-pre[j-1]))%mod+mod)%mod; } } } unordered_map
int> mp; inline int sum2(int n) { return 1LL*n*(n+1)%mod*(2*n+1)%mod*inv6%mod; } inline int sum3(int n) { int ans=1LL*n*(n+1)%mod*inv2%mod; return 1LL*ans*ans%mod; } inline int S(LL n) { if(n return sumiiphi[n]; if(mp.count(n)) return mp[n]; LL ans=sum3(n%mod);//n取模 for(LL l=2,r;l<=n;l=r+1) { r=n/(n/l); ans=((ans-1LL*S(n/r)*(sum2(r%mod)-sum2((l-1)%mod)))%mod+mod)%mod; } return mp[n]=ans; } int32_t main() { int t; scanf("%lld",&t); int k; init(); while(t--) { scanf("%lld%lld",&n,&k); mp.clear(); get_h(k); int ans=0; for(int i=1;i<=tol;i++) { ans=(ans+1LL*(hk[i]-hk[i-1])%mod*S(n/num[i])%mod+mod)%mod; } printf("%lld\n",ans); } }
1006 Fansblog
#includeusing namespace std; typedef long long LL; unordered_map mp; LL quick_pow(LL a,LL b,LL mod) { LL ans=1; while(b) { if(b&1) ans=((__int128)ans)*a%mod; a=((__int128)a)*a%mod; b>>=1; } return ans; } long long factor[110], cnt; long long Mul_Mod(long long a, long long b, long long c) { if (b == 0) return 0; long long ans = Mul_Mod(a, b / 2, c); ans = (ans * 2) % c; if (b % 2) ans = (ans + a) % c; return ans; } long long Pow_Mod(long long a, long long b, long long c) { if (b == 0) return 1; long long x = Pow_Mod(a, b / 2, c); if (x == 0) return 0; long long y = Mul_Mod(x, x, c); if (y == 1 && x != 1 && x != c - 1) return 0; if (b % 2) y = Mul_Mod(y, a, c); return y; } bool Miller_rabin(long long n, int timenum = 10) { if (n < 2) return false; if (n == 2) return true; while (timenum--) { if (Pow_Mod(rand() % (n - 2) + 2, n - 1, n) != 1) return false; } return true; } long long Gcd(long long a, long long b) { long long t; while (b) { t = a; a = b; b = t % b; } return a; } void Pollard(long long n); void Factor(long long n) { long long d = 2; while (true) { if (n % d == 0) { Pollard(d); Pollard(n / d); return; } d++; } } void Pollard(long long n) { if (n == 1) return; if (Miller_rabin(n)) { factor[cnt++] = n; return; } long long i = 0, k = 2, x, y, d; x = y = rand() % (n - 1) + 1; while (i++ < 123456) { x = (Mul_Mod(x, x, n) + n - 1) % n; d = Gcd((y - x + n) % n, n); if (d != 1) { Pollard(d); Pollard(n / d); return; } if (i == k) { y = x; k *= 2; } } Factor(n); } int main() { int t; scanf("%d",&t); LL p; while(t--) { scanf("%lld",&p); if(mp.count(p)) { printf("%lld\n",mp[p]); continue; } LL ans=p-1; if(Miller_rabin(p-2)) { LL ret=(LL)(((__int128)(p-1))*quick_pow(p-1,p-2,p)%p); mp[p]=ret; printf("%lld\n",ret); continue; } for(LL i=p-4;i>=998244353;i-=2) { ans=(__int128)ans*(i+1)%p*(i+2)%p; if(Miller_rabin(i)) { LL ret=(LL)(((__int128)(p-1))*quick_pow(ans,p-2,p)%p); mp[p]=ret; printf("%lld\n",ret); break; } } } }
1007 Find the answer
#include#define maxl 200010 using namespace std; int n,m; int a[maxl],dy[maxl],ans[maxl]; struct anode { int id,val; }aa[maxl]; struct node { int l,r; long long sum; }tree[maxl*4]; int b[maxl]; inline bool cmp(const anode &x,const anode &y) { return x.val<y.val; } inline void add(int i,int x) { while(i<=n) { b[i]+=x; i+=i&-i; } } inline int sum(int i) { int ret=0; while(i) { ret+=b[i]; i-=i&-i; } return ret; } inline void build(int k,int l,int r) { tree[k].l=l;tree[k].r=r; if(l==r) { tree[k].sum=aa[l].val; return; } int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum; } inline void prework() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]),aa[i].id=i,aa[i].val=a[i]; sort(aa+1,aa+1+n,cmp); for(int i=1;i<=n;i++) { dy[aa[i].id]=i; b[i]=0; } for(int i=1;i<=n;i++) add(i,1); build(1,1,n); } inline void upd(int k,int l) { if(tree[k].l==tree[k].r) { tree[k].sum=0; return; } int mid=(tree[k].l+tree[k].r)>>1; if(l<=mid) upd(k<<1,l); else upd(k<<1|1,l); tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum; } inline int query(int k,long long res) { if(tree[k].l==tree[k].r) { if(tree[k].sum>res) return tree[k].l-1; else return tree[k].l; } if(tree[k<<1].sum<res) return query(k<<1|1,res-tree[k<<1].sum); else return query(k<<1,res); } inline void mainwork() { int l; for(int i=n;i>=1;i--) { upd(1,dy[i]); add(dy[i],-1); l=query(1,m-a[i]); ans[i]=(i-1)-sum(l); } } inline void print() { for(int i=1;i<=n;i++) printf("%d ",ans[i]); puts(""); } int main() { int t; scanf("%d",&t); for(int i=1;i<=t;i++) { prework(); mainwork(); print(); } return 0; }
1008 Game
Unsolved.
1009 K Subsequence
https://blog.csdn.net/baiyifeifei/article/details/97706037
#includeusing namespace std; typedef pair<int, int> pii; const int maxn = 1e4; const int inf = 0x3f3f3f3f; struct edge { int to, cap, cost, rev; edge() {} edge(int to, int _cap, int _cost, int _rev) :to(to), cap(_cap), cost(_cost), rev(_rev) {} }; int V, H[maxn + 5], dis[maxn + 5], PreV[maxn + 5], PreE[maxn + 5]; vector G[maxn + 5]; void init(int n) { V = n; for (int i = 0; i <= V; ++i)G[i].clear(); } void AddEdge(int from, int to, int cap, int cost) { G[from].push_back(edge(to, cap, cost, G[to].size())); G[to].push_back(edge(from, 0, -cost, G[from].size() - 1)); } int Min_cost_max_flow(int s, int t, int f, int& flow) { int res = 0; fill(H, H + 1 + V, 0); while (f) { priority_queue int, int>, vector int, int>>, greater int, int>> > q; fill(dis, dis + 1 + V, inf); dis[s] = 0; q.push(pair<int, int>(0, s)); while (!q.empty()) { pair<int, int> now = q.top(); q.pop(); int v = now.second; if (dis[v] < now.first)continue; for (int i = 0; i < G[v].size(); ++i) { edge& e = G[v][i]; if (e.cap > 0 && dis[e.to] > dis[v] + e.cost + H[v] - H[e.to]) { dis[e.to] = dis[v] + e.cost + H[v] - H[e.to]; PreV[e.to] = v; PreE[e.to] = i; q.push(pair<int, int>(dis[e.to], e.to)); } } } if (dis[t] == inf)break; for (int i = 0; i <= V; ++i)H[i] += dis[i]; int d = f; for (int v = t; v != s; v = PreV[v])d = min(d, G[PreV[v]][PreE[v]].cap); f -= d; flow += d; res += d*H[t]; for (int v = t; v != s; v = PreV[v]) { edge& e = G[PreV[v]][PreE[v]]; e.cap -= d; G[v][e.rev].cap += d; } } return res; } int a[maxn]; int main() { int t; scanf("%d",&t); while(t--) { int n,k; scanf("%d%d",&n,&k); for(register int i=1;i<=n;++i) scanf("%d",&a[i]); int ss=0,s=1,t=2*n+2,tt=2*n+3; init(tt+1); AddEdge(ss,s,k,0); AddEdge(t,tt,k,0); for(register int i=1;i<=n;++i) { AddEdge(s,i+1,1,0); AddEdge(i+1+n,t,1,0); AddEdge(i+1,i+1+n,1,-a[i]); for(register int j=i+1;j<=n;++j) { if(a[j]>=a[i]) { AddEdge(1+i+n,1+j,1,0); } } } int ans=0; printf("%d\n",-Min_cost_max_flow(ss,tt,inf,ans)); } return 0; }
1010 Sindar's Art Exhibition
Unsolved.
1011 Squrirrel
题解:题目意思给你一棵树,每条边有一个权值。
让你求:在将一条边的权值变为零的情况下,一个点到其最远叶子节点的距离的最小值为多少。
思路:
先考虑在不使一条边变为零的情况下:我们先dfs处理出,每一个节点到其叶子节点的最远距离l[i],然后求出其沿着父亲节点的最远距离fa[i],则对于这个节点的就是max(l[i],fa[i]),然后在所有节点中的最大距离取个最小值就行了。 现在是可以任意一条边变为零,那么我们先dfs,记录每个节点到其叶子节点的最大值,次大值,第三大值,然后求出其沿着父亲节点的最大值,对于将边变为零的情况,我们只要在DP时加上一维,判断是否江一条边变为零就行了。
参考代码:
#includeusing namespace std; typedef long long ll; #define pii pair #define pil pair #define PI acos(-1.0) #define mkp make_pair #define mem(a,b) memset(a,b,sizeof(a)) const int INF=0x3f3f3f3f; const ll inf=0x3f3f3f3f3f3f3f3fll; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*f; } const int maxn=2e5+10; int T,n,cnt,head[maxn]; struct Edge{ int to,nxt,w; } edge[maxn<<1]; void AddEdge(int u,int v,int w) { edge[cnt].to=v; edge[cnt].w=w; edge[cnt].nxt=head[u]; head[u]=cnt++; } int dis[maxn],ans[maxn]; int f[maxn],s[maxn],t[maxn],fa[maxn][2]; int fi[maxn][2],se[maxn][2],th[maxn][2]; void Init() { cnt=0; mem(head,-1); mem(dis,0); mem(ans,0); for(int i=0;i<=n;++i) { fi[i][0]=fi[i][1]=0; se[i][0]=se[i][1]=0; th[i][0]=th[i][1]=0; fa[i][0]=fa[i][1]=0; f[i]=t[i]=s[i]=0; dis[i]=0; } } void dfs1(int x,int pre) { for(int i=head[x];~i;i=edge[i].nxt) { int v=edge[i].to,w=edge[i].w; if(v==pre) continue; dis[v]=w; dfs1(v,x); if(w+fi[v][0]>fi[x][0]) { th[x][0]=se[x][0]; t[x]=s[x]; se[x][0]=fi[x][0]; s[x]=f[x]; fi[x][0]=fi[v][0]+w; f[x]=v; } else if(w+fi[v][0]>se[x][0]) { th[x][0]=se[x][0]; t[x]=s[x]; se[x][0]=fi[v][0]+w; s[x]=v; } else if(w+fi[v][0]>th[x][0]) { th[x][0]=fi[v][0]+w; t[x]=v; } } fi[x][1]=min(fi[f[x]][0],dis[f[x]]+max(fi[f[x]][1],se[f[x]][0])); se[x][1]=min(fi[s[x]][0],dis[s[x]]+max(fi[s[x]][1],se[s[x]][0])); } void dfs2(int x,int pre) { ans[x]=min(max(fi[x][0],fa[x][1]),max(max(fi[x][1],se[x][0]),fa[x][0])); for(int i=head[x];~i;i=edge[i].nxt) { int v=edge[i].to,w=edge[i].w; if(v==pre) continue; if(f[x]==v) { fa[v][0]=max(fa[x][0],se[x][0])+w; fa[v][1]=min(max(fa[x][0],se[x][0]),min(max(fa[x][0],max(se[x][1],th[x][0])),max(se[x][0],fa[x][1]))+w); } else if(s[x]==v) { fa[v][0]=max(fi[x][0],fa[x][0])+w; fa[v][1]=min(max(fi[x][0],fa[x][0]),min(max(fa[x][0],max(fi[x][1],th[x][0])),max(fi[x][0],fa[x][1]))+w); } else { fa[v][0]=max(fi[x][0],fa[x][0])+w; fa[v][1]=min(max(fi[x][0],fa[x][0]),min(max(fa[x][0],max(fi[x][1],se[x][0])),max(fi[x][0],fa[x][1]))+w); } dfs2(v,x); } } int main() { T=read(); while(T--) { n=read(); Init(); int u,v,w; for(int i=1;i i) { u=read();v=read();w=read(); AddEdge(u,v,w);AddEdge(v,u,w); } dfs1(1,0); dfs2(1,0); int val=INF,pos; for(int i=1;i<=n;i++) { if(ans[i] i; else if(ans[i]==val&&i i; } printf("%d %d\n",pos,val); } return 0; } /* 1 5 1 5 1 1 2 1 2 3 2 3 4 1 */