• 2022/7/31


    707C - Pythagorean Triples

    这玩意竟然是有公式的,竟然没推出来,,,

    a为奇数时,b=(a²-1)/2,c=b+1,a为偶数是,b=a2/4-1 c=b+2.

    1. #include
    2. #define ll long long
    3. #define lowbit(x) ((x)&(-x))
    4. using namespace std;
    5. const ll MAX=1e6+5;
    6. const ll mod=998244353;
    7. ll a;
    8. int main(){
    9. cin>>a;
    10. if(a<=2){
    11. printf("-1\n");return 0;
    12. }
    13. ll b,c;
    14. if(a&1){
    15. b=(a*a-1)/2;c=b+1;
    16. }
    17. else{
    18. b=a*a/4-1;c=b+2;
    19. }
    20. printf("%lld %lld\n",b,c);
    21. system("pause");
    22. return 0;
    23. }

    1307C - Cow and Message

    算是前缀和类型的一道题吧,这次看了数据是不对的,以后会想不出反例来的,,,

    其实要符合等差数列这个条件最好是两个字母的,其次再是一个字母,字母越多符合条件的数量就越少,所以要求两个字母的如果两个字母相同那就是C(n,2),如果两个字母不同那就要看一下顺序了,毕竟ab,ba不是同一个,可以设一个这样的数组vis[i][j]表示ij这个字符串出现的次数,因为两个数的数列都是等差数列所以直接统计次数就可以,之后用ans获取最大值就可以了

    1. #include
    2. #define ll long long
    3. #define lowbit(x) ((x)&(-x))
    4. using namespace std;
    5. const ll MAX=1e6+5;
    6. const ll mod=998244353;
    7. string s;
    8. ll vis[30][30],cnt[30];
    9. int main(){
    10. cin>>s;
    11. ll ans=0;
    12. for(int i=0;ilength();i++){
    13. cnt[s[i]-'a']++;
    14. for(int j=0;j<26;j++){
    15. vis[j][s[i]-'a']+=cnt[j];
    16. }
    17. }
    18. for(int i=0;i<26;i++) vis[i][i]=(cnt[i]-1)*cnt[i]/2LL,ans=max(ans,cnt[i]);
    19. for(int i=0;i<26;i++)
    20. for(int j=0;j<26;j++)
    21. ans=max(ans,vis[i][j]);
    22. printf("%lld\n",ans);
    23. system("pause");
    24. return 0;
    25. }

    C - Zero Path dp

            如果n+m是偶数的话那么路径会有奇数步所以一定不对,设mx[i][j]为从1,1到i,j的路径中最大的为多少,mi[i][j]为最小的为多少,如果mi[n][m]<=0,mx[n][m]>=0,那么一定有解,这个也是可以证明的,大致的说一下就是你可以去修改路径上的一步让-1变为1或这相反,这代价会是-2,0,2中的一个,而mx和mi都是偶数,且0在[mi[n][m],mx[n][m]]中,所以总会有一条路径是可以的

    C. Zero Path_跑路的菜的博客-CSDN博客

    1. #include
    2. #define ll long long
    3. #define lowbit(x) ((x)&(-x))
    4. using namespace std;
    5. const ll MAX=1e6+5;
    6. const ll mod=998244353;
    7. ll t,n,m,a[1005][1005],mx[1005][1005],mi[1005][1005];
    8. int main(){
    9. scanf("%lld",&t);
    10. while(t--){
    11. scanf("%lld%lld",&n,&m);
    12. for(int i=1;i<=n;i++)
    13. for(int j=1;j<=m;j++) scanf("%lld",&a[i][j]),mx[i][j]=-1e18,mi[i][j]=1e18;
    14. mx[1][1]=mi[1][1]=a[1][1];
    15. for(int i=1;i<=n;i++)
    16. for(int j=1;j<=m;j++){
    17. if(i>1) mx[i][j]=max(mx[i-1][j]+a[i][j],mx[i][j]),mi[i][j]=min(mi[i][j],mi[i-1][j]+a[i][j]);
    18. if(j>1) mx[i][j]=max(mx[i][j],mx[i][j-1]+a[i][j]),mi[i][j]=min(mi[i][j],mi[i][j-1]+a[i][j]);
    19. }
    20. if((n+m)%2==0) printf("NO\n");
    21. else{
    22. if(mi[n][m]<=0&&mx[n][m]>=0) printf("YES\n");
    23. else printf("NO\n");
    24. }
    25. }
    26. system("pause");
    27. return 0;
    28. }

    CF246E Blood Cousins Return - 启发式合并 

    主要是如果统计不同的姓名,用一个map,ll>来表示这个姓名在第几层是否出现过,然后就可以来计数了,因为删除计数的时候也得靠map来统计,所以map要多清空一次,也正因为这多的一次差点超时,,但要是关了同步流应该就没啥问题了

    1. #include
    2. #define ll long long
    3. #define lowbit(x) ((x)&(-x))
    4. using namespace std;
    5. const ll MAX=1e6+5;
    6. const ll mod=998244353;
    7. ll n,m,tot[200005],ans[100005];
    8. ll son[100005],siz[100005],dep[100005],fson,f[100005];
    9. ll head[200005],cnt;
    10. string s[100005];
    11. map,ll>mp;
    12. struct node{
    13. ll val,id;
    14. };
    15. vectorq[100005];
    16. struct Edge{
    17. ll from,to,next;
    18. }edge[200005];
    19. void addedge(ll from, ll to){
    20. edge[++cnt].from = from;
    21. edge[cnt].to = to;
    22. edge[cnt].next =head[from];
    23. head[from] = cnt;
    24. }
    25. void dfs1(ll u,ll fa){
    26. siz[u]=1;dep[u]=dep[fa]+1;
    27. for(int i=head[u];i;i=edge[i].next){
    28. ll j=edge[i].to;
    29. if(j==fa) continue;
    30. dfs1(j,u);
    31. siz[u]+=siz[j];
    32. if(siz[j]>siz[son[u]]) son[u]=j;
    33. }
    34. }
    35. void cal(ll u,ll fa,ll val){
    36. if(!mp[{dep[u],s[u]}]) tot[dep[u]]+=val,mp[{dep[u],s[u]}]=1;
    37. for(int i=head[u];i;i=edge[i].next){
    38. ll j=edge[i].to;
    39. if(j!=fa&&j!=fson) cal(j,u,val);
    40. }
    41. }
    42. void dfs2(ll u,ll fa,ll keep){
    43. for(int i=head[u];i;i=edge[i].next){
    44. ll j=edge[i].to;
    45. if(j!=fa&&j!=son[u]) dfs2(j,u,0);
    46. }
    47. if(son[u]) dfs2(son[u],u,1),fson=son[u];
    48. cal(u,fa,1);
    49. fson=0;
    50. for(int i=0;isize();i++) ans[q[u][i].id]=tot[dep[u]+q[u][i].val];
    51. if(!keep) mp.clear(),cal(u,fa,-1),mp.clear();
    52. }
    53. int main(){
    54. scanf("%lld",&n);
    55. for(int i=1;i<=n;i++){
    56. cin>>s[i]>>f[i];
    57. if(f[i]) addedge(i,f[i]),addedge(f[i],i);
    58. }
    59. for(int i=1;i<=n;i++) if(!f[i]) dfs1(i,0);
    60. scanf("%lld",&m);
    61. for(int i=1;i<=m;i++){
    62. ll v,k;
    63. scanf("%lld%lld",&v,&k);
    64. q[v].push_back(node{k,i});
    65. }
    66. for(int i=1;i<=n;i++) if(!f[i]) dfs2(i,0,0);
    67. for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
    68. system("pause");
    69. return 0;
    70. }

    CF1009F Dominant Indices - 洛谷 | 启发式合并

    大部分都是对的,但是在统计深度的时候出现了错误,不应该统计差,应该直接统计深度,然后最后输出的时候再做差,因为直接统计差的话程序就直接比较差的最小值了,这显然是不对的

    题解 CF1009F 【Dominant Indices】 - EI psy congroo! - 洛谷博客

    1. #include
    2. #define ll long long
    3. #define lowbit(x) ((x)&(-x))
    4. using namespace std;
    5. const ll MAX=1e6+5;
    6. const ll mod=998244353;
    7. ll n,m,tot[MAX],ans[MAX];
    8. ll son[MAX],siz[MAX],dep[MAX],fson;
    9. ll head[MAX<<1],cnt;
    10. struct node{
    11. ll val,id;
    12. };
    13. vectorq[MAX];
    14. struct Edge{
    15. ll from,to,next;
    16. }edge[MAX<<1];
    17. void addedge(ll from, ll to){
    18. edge[++cnt].from = from;
    19. edge[cnt].to = to;
    20. edge[cnt].next =head[from];
    21. head[from] = cnt;
    22. }
    23. void dfs1(ll u,ll fa){
    24. siz[u]=1;dep[u]=dep[fa]+1;
    25. for(int i=head[u];i;i=edge[i].next){
    26. ll j=edge[i].to;
    27. if(j==fa) continue;
    28. dfs1(j,u);
    29. siz[u]+=siz[j];
    30. if(siz[j]>siz[son[u]]) son[u]=j;
    31. }
    32. }
    33. ll maxx,dis;
    34. void cal(ll u,ll fa,ll val,ll x){
    35. tot[dep[u]]+=val;
    36. if(tot[dep[u]]>maxx){
    37. maxx=tot[dep[u]],dis=dep[u];
    38. //if(x==1) cout<
    39. }
    40. else if(tot[dep[u]]==maxx) dis=min(dep[u],dis);
    41. //cout<
    42. for(int i=head[u];i;i=edge[i].next){
    43. ll j=edge[i].to;
    44. if(j!=fa&&j!=fson) cal(j,u,val,x);
    45. }
    46. }
    47. void dfs2(ll u,ll fa,ll keep){
    48. for(int i=head[u];i;i=edge[i].next){
    49. ll j=edge[i].to;
    50. if(j!=fa&&j!=son[u]) dfs2(j,u,0);
    51. }
    52. if(son[u]) dfs2(son[u],u,1),fson=son[u];
    53. cal(u,fa,1,u);
    54. //cout<
    55. fson=0;
    56. ans[u]=dis;
    57. if(!keep) cal(u,fa,-1,u),maxx=0,dis=0;
    58. }
    59. int main(){
    60. scanf("%lld",&n);
    61. for(int i=1;i
    62. ll u,v;
    63. scanf("%lld%lld",&u,&v);
    64. addedge(u,v);addedge(v,u);
    65. }
    66. dfs1(1,0);
    67. dfs2(1,0,0);
    68. for(int i=1;i<=n;i++) printf("%lld\n",ans[i]-dep[i]);
    69. system("pause");
    70. return 0;
    71. }

    CF375D Tree and Queries - 洛谷 | 启发式合并

    一发入魂,关键是要怎样处理大于等于k的颜色有多少种,可以发现每种颜色在计数时,每个颜色的每个数值只会出现一次,也就是说现在a颜色出现了5次,下一次再出现的话一定是又出现了一次变成了6次,那么我们就可以设一个这样的数组vis[i],表示出现了大于等于i次的颜色有多少个,询问的时候就可以直接加上了,具体看代码吧

    1. #include
    2. #define ll long long
    3. #define lowbit(x) ((x)&(-x))
    4. using namespace std;
    5. const ll MAX=1e6+5;
    6. const ll mod=998244353;
    7. ll n,m,tot[MAX],ans[MAX],c[MAX];
    8. ll son[MAX],siz[MAX],dep[MAX],fson;
    9. ll head[MAX<<1],cnt;
    10. struct node{
    11. ll val,id;
    12. };
    13. vectorq[MAX];
    14. struct Edge{
    15. ll from,to,next;
    16. }edge[MAX<<1];
    17. void addedge(ll from, ll to){
    18. edge[++cnt].from = from;
    19. edge[cnt].to = to;
    20. edge[cnt].next =head[from];
    21. head[from] = cnt;
    22. }
    23. void dfs1(ll u,ll fa){
    24. siz[u]=1;dep[u]=dep[fa]+1;
    25. for(int i=head[u];i;i=edge[i].next){
    26. ll j=edge[i].to;
    27. if(j==fa) continue;
    28. dfs1(j,u);
    29. siz[u]+=siz[j];
    30. if(siz[j]>siz[son[u]]) son[u]=j;
    31. }
    32. }
    33. ll vis[100005];
    34. void cal(ll u,ll fa,ll val){
    35. ll x=tot[c[u]];
    36. tot[c[u]]+=val;
    37. if(val==-1) vis[x]+=val;
    38. else vis[tot[c[u]]]+=val;
    39. //if(tot[c[u]]==4) cout<
    40. for(int i=head[u];i;i=edge[i].next){
    41. ll j=edge[i].to;
    42. if(j!=fa&&j!=fson) cal(j,u,val);
    43. }
    44. }
    45. void dfs2(ll u,ll fa,ll keep){
    46. for(int i=head[u];i;i=edge[i].next){
    47. ll j=edge[i].to;
    48. if(j!=fa&&j!=son[u]) dfs2(j,u,0);
    49. }
    50. if(son[u]) dfs2(son[u],u,1),fson=son[u];
    51. cal(u,fa,1);
    52. //cout<
    53. fson=0;
    54. //if(u==1) for(int i=1;i<=10;i++) cout<
    55. for(int i=0;isize();i++) ans[q[u][i].id]=vis[q[u][i].val];
    56. if(!keep) cal(u,fa,-1);
    57. }
    58. int main(){
    59. scanf("%lld%lld",&n,&m);
    60. for(int i=1;i<=n;i++) scanf("%lld",&c[i]);
    61. for(int i=1;i
    62. ll u,v;
    63. scanf("%lld%lld",&u,&v);
    64. addedge(u,v);addedge(v,u);
    65. }
    66. for(int i=1;i<=m;i++){
    67. ll u,k;
    68. scanf("%lld%lld",&u,&k);
    69. q[u].push_back(node{k,i});
    70. }
    71. dfs1(1,0);
    72. dfs2(1,0,0);
    73. for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
    74. system("pause");
    75. return 0;
    76. }

  • 相关阅读:
    R语言使用rbind函数将多个dataframe数据纵向合并起来创建dataframe数据、按照行合并dataframe
    B. Boboniu Plays Chess
    网络安全——cobalt Strike 之office钓鱼
    利用Timer实现窗体淡入淡出的效果
    【附源码】计算机毕业设计SSM社区便捷管理系统
    《Effective C++》系列之导读部分
    Linux操作系统
    【信号去噪】基于变分贝叶斯卡尔曼滤波器实现信号滤波附matlab代码
    SpringBoot 刷新上下文5--处理其他注解
    [iOS]MonkeyDev安装
  • 原文地址:https://blog.csdn.net/weixin_52621204/article/details/126082594