每一年都奔走在自己热爱里

没有人是一座孤岛,总有谁爱着你

AtCoder Beginner Contest 298(D,F)

AtCoder Beginner Contest 298(D,F)

D(思维,模拟,快速幂)

D

大意是最初有一个数字1,然后进行q个操作

有三种操作

1,输入1,x,在原来的数字后面添加一个尾数,例如原本的数是12,输入了15,数字变成了125

2,输入2,把原来的数字第一位数删除,例如原本的数是125,输入了2,数字变成了12

3,输入3,我们需要输出此时的数字(对一个数取模)

一开始我想的比较复杂

其实对于添加,我们只需乘10x

对于删除,我们只需要让此时的数字减去此时的数的首位乘上10len,所以,我们需要记录首位数(可以用队列),还有长度

但是,这里要注意一下,就是相减

正确的处理如下

//a-=b,%mod
a=((a-b)%mod+mod)%mod;
//而不是 a=(a-b+mod)%mod,有可能这个b非常大,加了mod后还是负数,不能把最后的答案变成正数
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define mem(a,b) memset((a),(b),sizeof(a))
const int maxn=6e5+10;
const int mod=998244353;
int n,q;
int ans=1;
int len=0;
int l=1;
queue<int>qq;
int ksm(int x,int p)
{
    int res=1;
    while (p)
    {
        if(p&1)
        {
            res=res*x%mod;
        }
        x=x*x%mod;
        p>>=1;
    }
    return res;
}
int inv(int x)
{
    return ksm(x,mod-2);
}
signed main ()
{
    cin>>q;
    qq.push(1);
    while (q--)
    {
        int op;
        cin>>op;
        if(op==1)
        {
            int x;
            cin>>x;
            qq.push(x);
            ans=(ans*10ll+x)%mod;
            len++;
        }
        else if(op==2)
        {
            int top=qq.front();
            qq.pop();
            int p=(top*ksm(10,len)%mod)%mod;
            ans=((ans-p)%mod+mod)%mod;
              len --;
        }
        else if(op==3)
        {
             cout<<ans<<"\n";
        }
    }
    system ("pause");
    return 0;
}

这次我的e过了,很简单的一个概率dp,这里就不写了

F(set,思维)

F

题目大意是有一个很大的网格,只有其中的n个位置有数在这些位置上,其他的都是0

我们选择一对x,y,x行和y列的这个十字架上面的所有位置的和,求这个和的最大值

我们先预先处理好行的和sumx和列的和sumy

有两种情况

x,y上面有数据,那么此时的和就是sumx[x]+sumy[y]a[x][y](两个都加了一次,这个位置加了两次)

x,y上面没有数据,直接相加

对于x,y上面没有数据,我们可以枚举每一个出现过数据的行,然后再在后面的那些没有和这一个行有关系的列中选择,由于不用减,故直接选择较大的那一个,(对于可以很容易删除,可以很容易得到最大值的那一个,我们可以想到set),后来还有记得把原来删除的列的数据加回来,比较每一个行所相关联的列都是不一样的)

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define mem(a,b) memset((a),(b),sizeof(a))
const int maxn=6e5+10;
const int mod=998244353;
int n;
struct node
{
    int x,y,val;
}a[maxn];
map<int,int>sumx,sumy;
set<pair<int,int>>py,px;
map<int,vector<int>>pei;
signed main ()
{
    cin>>n;
    for (int i=1;i<=n;i++)
    {
        cin>>a[i].x>>a[i].y>>a[i].val;
        sumx[a[i].x]+=a[i].val;
        sumy[a[i].y]+=a[i].val;
        pei[a[i].x].push_back(a[i].y);
    }
    int ans=0;
    for (int i=1;i<=n;i++)
    {
        int now=sumx[a[i].x]+sumy[a[i].y]-a[i].val;
        ans=max(ans,now);
    }
    for (auto [y,sum]:sumy)
    {
        py.insert({sum,y});
    }
    for (auto [x,sum]:sumx)
    {
        px.insert({sum,x});
    }
    for (auto [sum,x]:px)
    {
        for (auto y:pei[x])//和x行相关联的y
        {
            py.erase({sumy[y],y});
        }
        if(py.size())
        {
            int now=sum+(*(--py.end())).first;
            ans=max(ans,now);
        }
        for (auto y:pei[x])
        {
            py.insert({sumy[y],y});
        }
    }
    cout<<ans<<"\n";
    system ("pause");
    return 0;
}
posted @   righting  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示