T1 数对统计

分析

此题中,本质不同意味着两个数对长得不一样即可,顺序不同算两个。设两个数为 ( l , r ) (l,r) (l,r) 于是我们可以只枚举 l l l 有多少种选择,然后找 r r r 可以有几种选择。这里,对于两个相同但下标不一样的 l l l ,我们只算最前面的 l l l ,因为如果以后面的 l l l 为第一个数的话,在它后面的可供选择的 r r r 也一定可以被前面的 l l l 选择到,故不可能是最优解。

关于找 r r r 的方法,由于只要求 r r r 的种数,则可以采用后缀和处理。这样,对于一个枚举到的 l l l ,我们只需要将 l l l 后的 r r r 种数(后缀和数组)累加到答案里去即可。

时间复杂度 O ( n ) O(n) O(n) 。

Code

#include<bits/stdc++.h>
using namespace std;
long long n,a[100010],ans=0,s[100010],sum=0;
bool vh[100010],f[100010];
int main(){memset(vh,0,sizeof(vh));memset(f,0,sizeof(f));cin>>n;for(long long i=1;i<=n;++i) cin>>a[i];for(long long i=n;i>=1;--i){if(!vh[a[i]]) sum++;//如不同,可供选择的r数+1vh[a[i]]=1;s[i]=sum;}for(long long i=1;i<=n;++i){if(f[a[i]]) continue;f[a[i]]=1;ans+=s[i+1];}cout<<ans<<endl;return 0;
}

相似题目:Luogu P3901 数列找不同

T2 序列操作

分析

弱化版的[CSP-S2020] 函数调用。

最暴力的做法 O ( n 2 ) O(n^2) O(n2) ,不讲。

次暴力的做法 O ( n log ⁡ n ) O(n\log n) O(nlogn) 线段树,麻烦,不讲。

操作只有全乘和单加,单加相当于在原来的 a a a 数组下方缀一个新的数,用一个 m p mp mp 记录它是在进行了几次全乘操作后加上去的。这样对于每一个数,只需在最后乘上( 总 共 乘 了 多 少 总共乘了多少 总共乘了多少 除以 它 少 乘 了 多 少 它少乘了多少 它少乘了多少),最后累加到 a a a 数组即可得到最终答案。而( 总 共 乘 了 多 少 总共乘了多少 总共乘了多少 除以 它 少 乘 了 多 少 它少乘了多少 它少乘了多少)可以通过 “ 后缀积 ” 来解决。

时间复杂度 O ( n ) O(n) O(n) 。

Code

#include<bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
struct nod{long long add,mp;
};
long long n,q,cp,cd,am,pos=1,sm[200010],hm[200010],ans[200010];
char aom;
vector<nod>w[200010];
int main(){cin>>n>>q;sm[1]=1;for(long long i=1;i<=q;++i){cin>>aom;if(aom=='+'){cin>>cp>>cd;w[cp].push_back(nod{cd,pos+1});//缀上一个数}else{cin>>am;sm[++pos]=am;}}hm[pos+1]=1;for(long long i=pos;i>=1;--i){hm[i]=(hm[i+1]*sm[i])%mod;//后缀积}for(long long i=1;i<=n;++i){for(long long j=0;j<w[i].size();++j){ans[i]=(ans[i]+w[i][j].add*hm[w[i][j].mp])%mod;//累加}cout<<ans[i]<<' ';}cout<<endl;return 0;
}

T3 菜单设计

分析

看数据量就知道状压 d p dp dp ……

设 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示在二进制状态 i i i 下,上一个选择的菜肴是 j j j 号。根据题意,可以选择一个搭配的菜以获得特殊加成,也可以选择一道不搭配的菜。我们把不搭配的菜视为特殊加成为 0 0 0 ,现在我们选第 k k k 号菜,则递推式为:
d p [ i ∣ ( 1 < < ( k − 1 ) ) ] [ k ] = m a x ( d p [ i ∣ ( 1 < < ( k − 1 ) ) ] [ k ] , d p [ i ] [ j ] + v a l [ k ] + w [ j ] [ k ] ) dp[i|(1<<(k-1))][k]=max(dp[i|(1<<(k-1))][k],dp[i][j]+val[k]+w[j][k]) dp[i∣(1<<(k−1))][k]=max(dp[i∣(1<<(k−1))][k],dp[i][j]+val[k]+w[j][k])
代码也就基本上没难度了。

时间复杂度 O ( 2 n n 2 ) O(2^nn^2) O(2nn2) (实际上可以优化 n 2 n^2 n2 那里的枚举,减少很多枚举量)。

Code

#include<bits/stdc++.h>
using namespace std;
long long n,m,dp[300010][20],val[20],w[20][20],q,cx,cy,cz,mx,ans=0;
long long vd[20],vn[20],pd,pn,cf,t;
long long _max(long long u,long long v){//手写max卡卡常return u>v?u:v;
}
int main(){memset(dp,0,sizeof(dp));memset(w,0,sizeof(w));cin>>n>>m;mx=(1<<n);for(long long i=1;i<=n;++i) cin>>val[i];cin>>q;for(long long i=1;i<=q;++i){cin>>cx>>cy>>cz;w[cx][cy]=cz;}for(long long i=0;i<n;++i) dp[1<<i][i+1]=val[i+1];for(long long i=1;i<mx;++i){if(__builtin_popcountll(i)>=m) continue;cf=1,pd=0,pn=0,t=1;while(cf<mx){if(cf&i) vd[++pd]=t;//vd存已选else vn[++pn]=t;//vn存未选t++,cf*=2;}for(long long j=1;j<=pd;++j){for(long long k=1;k<=pn;++k){dp[i|(1<<(vn[k]-1))][vn[k]]=_max(dp[i|(1<<(vn[k]-1))][vn[k]],dp[i][vd[j]]+val[vn[k]]+w[vd[j]][vn[k]]);}}}for(long long i=0;i<mx;++i){if(__builtin_popcountll(i)==m){for(long long j=1;j<=n;++j) ans=_max(ans,dp[i][j]);}}cout<<ans<<endl;return 0;
}

注:__builtin_popcount(x) 表示求 x x x 在二进制下的 1 1 1 的个数(后面带 l l ll ll表示返回类型为 l o n g long long l o n g long long )。

T4 树的链接

一开始没看标题,以为是张图,看到

数据保证,在任何链接操作之前,所链接的两个点 x x x 与 y y y 之间不存在任何路径。

这句话时才发现理解错了,白浪费10分钟。

如果这是个树,就比较好做了:

对于任意两个点 i , j i,j i,j ,当它们之间联通时,则有且只有一条路径,那么这条路必然是最短路径。先考虑联通性问题,这可以用并查集高效解决。再考虑求路径问题,这是重难点:

首先,把询问存下来。因为如果在加边时两个点有路径,那么在树成型时这个路径是不变的,只需要记录一下无路径的询问即可。那么,问题转化成:在一棵树上,求两点之间距离。其中这个边是有长度的。

受Luogu P3258 [JLOI2014]松鼠的新家启发,我想到如下算法(类似 l c a lca lca ):

设 s p [ i ] [ j ] sp[i][j] sp[i][j] 为点 i i i 向上跳 2 j 2^j 2j 步的路径长度(根往上跳还是根,长度不变)。则类似 l c a lca lca 处理方式, s p sp sp 数组就可以根据递推关系:
s p [ i ] [ j ] = s p [ i ] [ j − 1 ] + s p [ a n c [ i ] [ j − 1 ] ] [ j − 1 ] ; sp[i][j]=sp[i][j-1]+sp[anc[i][j-1]][j-1]; sp[i][j]=sp[i][j−1]+sp[anc[i][j−1]][j−1];
来处理( a n c anc anc 数组为已经提前处理好的 从 i i i 点向上跳 2 j 2^j 2j 步所到达的点)。

那么,求两点之间路径长时,可以先找 l c a lca lca ,然后从两个点往上倍增跳到 l c a lca lca 处,统计 s p sp sp 数组总和即可。

时间复杂度 O ( m a x ( n , q ) log ⁡ n ) O(max(n,q)\log n) O(max(n,q)logn) 。

Code

#include<bits/stdc++.h>
using namespace std;
struct nod{int to,d;
};
int n,q,cu,cv,cw,ctsp,qr[300010][2],pq=0,depth[300010];
int f[300010];
bool dlt[300010],vis[300010];
int anc[300010][25],sp[300010][25];
vector<nod>w[300010];
int findf(int k){return k==f[k]?k:f[k]=findf(f[k]);
}
string str;
void build(int now){vis[now]=1;depth[now]=depth[anc[now][0]]+1;for(int i=0;i<w[now].size();++i){if(w[now][i].to==anc[now][0]) continue;anc[w[now][i].to][0]=now;sp[w[now][i].to][0]=w[now][i].d;build(w[now][i].to);}
}
void lcanc(){for(int i=1;i<=20;++i){for(int j=1;j<=n;++j){anc[j][i]=anc[anc[j][i-1]][i-1];sp[j][i]=sp[j][i-1]+sp[anc[j][i-1]][i-1];}}
}
int getlca(int x,int y){if(depth[x]<depth[y]) swap(x,y);for(int i=20;i>=0;--i) if(depth[anc[x][i]]>=depth[y]) x=anc[x][i];if(x==y) return x;for(int i=20;i>=0;--i) if(anc[x][i]!=anc[y][i]) x=anc[x][i],y=anc[y][i];return anc[x][0];
}
int main(){cin>>n>>q;getchar();for(int i=1;i<=n;++i) f[i]=i;for(int i=1;i<=q;++i){cu=0,cv=0,cw=0;getline(cin,str);ctsp=0;int j=0;while(str[j]!=' ') cu=cu*10+str[j]-'0',j++;j++;while(j<str.size()&&str[j]!=' ') cv=cv*10+str[j]-'0',j++;if(j!=str.size()){j++;while(j<str.size()) cw=cw*10+str[j]-'0',j++;w[cu].push_back(nod{cv,cw});w[cv].push_back(nod{cu,cw});f[findf(cu)]=findf(cv);}else{qr[++pq][0]=cu,qr[pq][1]=cv;int fu=findf(cu),fv=findf(cv);if(fu!=fv) dlt[pq]=1;else dlt[pq]=0;}}anc[1][0]=1,sp[1][0]=0;for(int i=1;i<=n;++i) if(!vis[i]) build(i);lcanc();for(int i=1;i<=pq;++i){if(dlt[i]){cout<<-1<<endl;continue;}int l=qr[i][0],r=qr[i][1];int lca=getlca(l,r),ans=0;for(int i=20;i>=0;--i) if(depth[anc[l][i]]>=depth[lca]) ans+=sp[l][i],l=anc[l][i];for(int i=20;i>=0;--i) if(depth[anc[r][i]]>=depth[lca]) ans+=sp[r][i],r=anc[r][i];cout<<ans<<endl;}return 0;
}

IAISH 2022.11月赛 乙组相关推荐

  1. 上海11月月赛乙组解题报告

    上海11月月赛乙组解题报告 1.数对统计 题目描述 给定 n 个数字 a1,a2,--,an,请从中挑选两个数字,并按原顺序组成一个数对.请问能选出多少种不完全相等的数对? 输入格式 第一行,单个整数 ...

  2. 上海2022年11月月赛丙组

    上海2022年11月月赛丙组 T1~T4略 T5 出栈序列 题目描述 给定一个长度为 n n n的.仅由小写字母组成的字符串,将其按序依次放入栈中. 请问在所有可能的出栈序列中,字典序最小的出栈序列是 ...

  3. 上海市计算机学会月赛 2022年7月月赛丙组

    上海市计算机学会月赛 2022年7月月赛丙组 水仙花指数 因数之和 观光电梯 匹配括号(三) 打印六芒星 本文仅供学术探讨 水仙花指数 内存限制: 256 Mb时间限制: 1000 ms 题目描述 定 ...

  4. 上海市计算机学会月赛 2022年9月月赛丙组

    上海市计算机学会月赛 2022年9月月赛丙组 这次题目真的衡水 矩形的周长与面积 机会成本 三色排序 阶乘尾数 前序中序转后序 这次题目真的衡水 文章拖了好久忘记发了 明天初赛祝各位考试顺利有一个好的 ...

  5. 上海市计算机学会2022年10月月赛丙组解题报告

    上海市计算机学会2022年10月月赛丙组解题报告 直角三角形的判定 题目描述 给定三个正整数表示三角形的三条边,请判定它是否为直角三角形 输入格式 第一行:三个整数 a,b 与 c 输出格式 若可以构 ...

  6. 网上IC笔试面试题目与秋招进度(2022.11.5更新)

    2022.11.5更新:(IC笔试题目有JL科技.TR半导体.HZW.MX半导体.RSKX)欢迎大家一起讨论题目,也请多多指教弟弟.笔试已经转移到新开帖子了. 目前投递60+,人才库8,offer6拒 ...

  7. 2022/11/27一周总结

    项目 redis 安装以及启动 切换到redis根目录运行cmd,先启动服务端 redis-server.exe 2.输入redis-cli并回车(redis-cli是客户端程序)如图正常提示进入,并 ...

  8. 「CodePlus 2017 11 月赛」可做题

    题目描述 qmqmqm 希望给 sublinekelzrip 出一道可做题.于是他想到了这么一道题目:给一个长度为n的非负整数序列ai​​,你需要计算其异或前缀和bi,满足条件b1=a1​​,bi=b ...

  9. [CodePlus 2017 11月赛]晨跑 题解(辗转相除法求GCD)

    [CodePlus 2017 11月赛]晨跑 Description "无体育,不清华"."每天锻炼一小时,健康工作五十年,幸福生活一辈子".在清华,体育运动绝 ...

最新文章

  1. JAVA中的Font
  2. pxe网络安装操作系统 原理与详细过程
  3. C++ Primer 5th笔记(chap 16 模板和泛型编程)类模板和static
  4. 事务例子_Redis事务系列之一Redis事务详解
  5. SpatialHadoop中空间索引系列之(四)空间格网索引实现
  6. 蓝桥杯 ADV-110 算法提高 温度转换
  7. 如何正确认识大数据分析
  8. shell 命令set -e的作用
  9. easydarwin 安装_easydarwin支持什么格式
  10. 微软输入法数字有间隔_各种中文输入法中输入间隔号“·”的措施
  11. [3维影像]360度杯子环绕拍摄
  12. 如何激活优动漫PAINT,获取优动漫PAINT序列号
  13. 纯音乐自制吉他及钢琴简谱合集
  14. 年末去字节跳动面试,居然被面试官问的哑口无言,原因竟然是这个!!!
  15. HP LaserJet 1020打印机显示脱机,脱机使用打印机的勾去不掉
  16. SPI接口的MISO和MOSI连接时注意
  17. LeetCode分类刷题----链表篇
  18. 杭电2019多校第三场 HDU-6608 Fansblog(威尔逊定理+素数间隔+逆元)
  19. 百度输入法android+4.8,百度输入法Android v7.6来了 翻译功能上线助力跨国沟通
  20. Java 程序获取本机 ip 地址

热门文章

  1. elasticsearch win7集群配置python测试
  2. 一般的在线教育平台需具备哪些功能?
  3. 开源|快速入门和理解并模拟实现GPS户外机器人的定位与导航
  4. 普罗米修斯监控系统_一步步教你用Prometheus搭建实时监控系统系列(二)——详细分析拉取和推送两种不同模式...
  5. 这五个能堪比手机App的逆天小程序,拥有它们你就无敌了!
  6. 国内首条“无人驾驶”地铁北京燕房线首段试跑
  7. 什么是Socket?
  8. 主键顺序影响——如何优化 ClickHouse 索引(二)
  9. Matlab学习笔记(数学函数)一
  10. 【Java二十周年】春风十里,不如你