2020HDU多校第二场By Rynar 6763-6774
1001.Total Eclipse
思路:从大到小建树,利用并查集路径压缩
int n,m,k;
int a[N],rk[N],f[N],vis[N],fa[N];
vector<int>v[N];
int ff(int x){
if (f[x]==x)return x;
return f[x]=ff(f[x]);
}
bool cmp(int x,int y){
return a[x]>a[y];
}
void solve(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++){
scanf("%d",&a[i]);
rk[i]=f[i]=i;
fa[i]=vis[i]=0;
v[i].clear();
}
sort(rk+1,rk+1+n,cmp);
for (int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);v[y].push_back(x);
}
for (int i=1;i<=n;i++){
int x=rk[i];
vis[x]=1;
for (int j:v[x]){
if (vis[j]){
int y=ff(j);
if (x!=y){
fa[y]=f[y]=x;
}
}
}
}
ll ans=0;
for(int i=1;i<=n;i++)ans+=a[i]-a[fa[i]];
printf("%lld\n",ans);
}
int main() {
int T;
cin>>T;
while (T--)solve();
return 0;
}
1002.Blood Pressure Game
1003.Count on a Tree II Striking Back
1004.Diamond Rush
1005.New Equipments
思路:zkw费用流,建图进行增广路
const int N=1e5+10;
const ll inf=1e16;
int n,m,k;
struct zkw{
ll Cost=0,Flow=0;
ll vis[N],dis[N],head[N];
int step,n;
struct node{
ll to,cap,cost,n;
}e[N<<1];
void add(int x,int y,int v,ll c){
e[step].to=y;
e[step].cap=v;
e[step].cost=c;
e[step].n=head[x];
head[x]=step++;
e[step].to=x;
e[step].cap=0;
e[step].cost=-c;
e[step].n=head[y];
head[y]=step++;
}
bool spfa(int s,int t){
for(int i=0;i<=n;i++) vis[i]=0,dis[i]=inf;//要改
deque<int>q;
q.push_back(t);
dis[t]=0;
vis[t]=1;
while(!q.empty()){
int u=q.front();
q.pop_front();
for(int i=head[u];~i;i=e[i].n){
int v=e[i].to;
if(e[i^1].cap&&dis[v]>dis[u]+e[i^1].cost){
dis[v]=dis[u]+e[i^1].cost;
if(!vis[v]){
vis[v]=1;
if(!q.empty()&&dis[v]<dis[q.front()])//SLF优化
q.push_front(v);
else q.push_back(v);
}
}
}
vis[u]=0;
}
return dis[s]<inf;
}
int dfs(int s,int t,ll flow){
vis[s]=1;
if(s==t||flow<=0) return flow;
int res,used=0;
for(int i=head[s];~i;i=e[i].n){
int v=e[i].to;
if(!vis[v]&&e[i].cap&&dis[s]-dis[v]==e[i].cost){
res=dfs(v,t,min(e[i].cap,flow-used));
if(res) {
e[i].cap-=res;
e[i^1].cap+=res;
Cost+=res*e[i].cost;
used+=res;
}
if(used==flow)break;
}
}
return used;
}
void solve(int s,int t){
while(spfa(s,t)){
vis[t]=1;
while(vis[t]){
for(int i=0;i<=n;i++) vis[i]=0;//要改
Flow+=dfs(s,t,inf);
}
}
}
void init(int n){
step=0;
Flow=Cost=0;
memset(head,-1,sizeof head);
this->n=n;
}
}zkw;
ll a[N],b[N],c[N],uni[N];
struct node{
ll x,y,id;
bool operator<(const node& k)const{
return y==k.y?x<k.x:y<k.y;
}
};
vector<node>p;
void solve(){
ll n,m;
scanf("%lld%lld",&n,&m);
for (int i=1;i<=n;i++){
scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
}
p.clear();
int tot=n+2;
for (int i=1;i<=n;i++){
double dx=-0.5*b[i]/a[i];
int l=floor(dx),r=ceil(dx);
if (l==r)r++;if (l>m)l=m;if (r<=0)r=1;
int cnt=tot;
while (cnt>0){
if (l>0){
p.push_back({l,a[i]*l*l+b[i]*l+c[i],i-1});
l--;cnt--;
}
if (r<=m){
p.push_back({r,a[i]*r*r+b[i]*r+c[i],i-1});
r++;cnt--;
}
if (l<=0&&r>m)break;
}
}
sort(p.begin(),p.end());
int s=0,t=3000;
zkw.init(t+1);
int cntp=p.size();
for (int i=0;i<p.size();i++){
uni[i]=p[i].x;
}
sort(uni,uni+cntp);
cntp=unique(uni,uni+cntp)-uni;
for (int i=0;i<p.size();i++) {
p[i].x=lower_bound(uni,uni+cntp,p[i].x)-uni;
}
for (int i=1;i<=n;i++) {
zkw.add(1,1+i,1,0);
}
for (int i=0;i<p.size();i++) {
zkw.add(p[i].id+2,n+2+p[i].x,1,p[i].y);
}
for (int i=0;i<cntp;i++){
zkw.add(n+2+i,t,1,0);
}
for (int i=0;i<n;i++){
zkw.add(s,1,1,0);
zkw.solve(s,t);
if (i==n-1) printf("%lld\n",zkw.Cost);
else printf("%lld ",zkw.Cost);
}
}
int main(){
int T;
scanf("%d",&T);
while (T--){
solve();
}
return 0;
}
1006.The Oculus
思路:斐波那契数列循环节
const int N=2e6+10;
const ll mod=998244353;
int n,m,k;
int a[N],b[N],c[N];
ll f[N];
void solve(){
scanf("%d",&n);
for (int i=1;i<=n;i++)scanf("%d",&a[i]);
scanf("%d",&m);
for (int i=1;i<=m;i++)scanf("%d",&b[i]);
scanf("%d",&k);
for (int i=1;i<=k;i++)scanf("%d",&c[i]);
ll sa,sb,sc;sa=sb=sc=0;
for (int i=1;i<=k;i++)if (c[i])sc=(sc+f[i])%mod;
for (int i=1;i<=n;i++)if (a[i])sa=(sa+f[i])%mod;
for (int i=1;i<=m;i++)if (b[i])sb=(sb+f[i])%mod;
sc=(sa*sb%mod-sc+mod)%mod;
c[k+1]=0;
for (int i=1;i<=k;i++){
if (sc==f[i]&&c[i-1]==0&&c[i]==0&&c[i+1]==0){
printf("%d\n",&i);
break;
}
}
}
int main(){
int T;
f[0]=1;f[1]=1;
for (int i=1;i<N;i++)f[i+1]=(f[i]+f[i-1])%mod;
cin>>T;
while (T--){
solve();
}
return 0;
}
1007.In Search of Gold
1008.Dynamic Convex Hull
1009.It's All Squares
1010.Lead of Wisdom
思路:暴搜
const int N=50+10;
int n,k;
struct node{
int a,b,c,d;
};
ll ans=0;
vector<node>v[N],p[N];
void dfs(int x,int a,int b,int c,int d){
if (x==k+1){
ans=max(ans,1ll*(a+100)*(b+100)*(c+100)*(d+100));
return;
}
for (node i:v[x]){
dfs(x+1,a+i.a,b+i.b,c+i.c,d+i.d);
}
}
void solve(){
scanf("%d%d",&n,&k);
for (int i=1;i<=k;i++)v[i].clear(),p[i].clear();
ans=0;
int t,a,b,c,d;
for (int i=1;i<=n;i++){
scanf("%d%d%d%d%d",&t,&a,&b,&c,&d);
p[t].push_back({a,b,c,d});
}
int cnt=0,a1,b1,c1,d1;a1=b1=c1=d1=0;
for (int i=1;i<=k;i++){
if (p[i].size()==1){
a1+=p[i][0].a;b1+=p[i][0].b;c1+=p[i][0].c;d1+=p[i][0].d;
}
else if (p[i].size()){
v[++cnt]=p[i];
}
}
k=cnt;
dfs(1,a1,b1,c1,d1);
printf("%lld\n",ans);
}
int main() {
int T;
cin>>T;
while (T--)solve();
return 0;
}
1011.King of Hot Pot
1012.String Distance
思路:序列自动机+dp
const int N=1e5+10;
const int inf=0x3f3f3f3f;
int n,m,k,q;
char s1[N],s2[N];
int nxt[N][27],dp[21][21];
void init(char *s){//序列自动机,nxt[i][j]记录i-len的第一个j出现的位置
int len=strlen(s);
for(int i=0;i<26;i++) nxt[len][i]=inf;
for(int i=len-1;i>=0;i--){
for(int j=0;j<26;j++)nxt[i][j]=nxt[i+1][j];
nxt[i][s[i]-'a']=i;
}
}
void solve(){
scanf("%s%s",s1,s2);
init(s1);
int m=strlen(s2);
scanf("%d",&q);
while (q--){
int l,r;
scanf("%d%d",&l,&r);
l--;r--;
int ans=0;
memset(dp,inf,sizeof(dp));//dp[i][j]代表与s2[1-i]公共子序列已经累计j个元素的最短前缀位置
for (int i=0;i<m;i++)dp[i][1]=nxt[l][s2[i]-'a'];
for (int i=1;i<m;i++){
for (int j=1;j<=i+1;j++){
dp[i][j]=min(dp[i][j],dp[i-1][j]);
if (dp[i-1][j-1]<r)dp[i][j]=min(dp[i][j],nxt[dp[i-1][j-1]+1][s2[i]-'a']);
}
}
for (int i=m;i>=1;i--){
if (dp[m-1][i]<=r){
ans=i;
break;
}
}
ans=r-l+1+m-ans*2;
printf("%d\n",ans);
}
}
int main() {
int T;
scanf("%d",&T);
while (T--)solve();
return 0;
}
禁止类似码农教程的网站爬取,抄袭博客内容。
https://www.cnblogs.com/rair/

浙公网安备 33010602011771号