Codeforces #187Div2

刚打完一场CF打算歇一下,然后fsf很淡然地又帮我点开了个Virtual.
然后就哭着又做了一场……
显然这场没有上一场做得好……


A:
给你n个瓶子,每个瓶子有瓶盖的品牌和这个瓶盖能开启哪种品牌。
现在问最后剩下几个瓶子开不开。
(n <= 100)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define Rep(i,n) for(int i = 1;i <= n;i ++)
using namespace std;
const int N = 1005;
int u[N],v[N];
bool vis[N];
int main ()
{
    int n;
    scanf("%d",&n);
    Rep(i,n)
        scanf("%d%d",&u[i],&v[i]);
    Rep(i,n)
    {
        Rep(j,n)
            if(i != j)
            {
                if(u[j] == v[i])vis[j] = 1;
            }
    }
    int cnt = 0;
    Rep(i,n)if(!vis[i])cnt ++;
    printf("%d\n",cnt);
    return 0;
}

B:
给定一个序列,每次进行3种操作:
1.把 ai 变成v
2.所有数+x
3.询问a_i的值。
我们开个全局变量一搞就好了,复杂度 O(n)

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define Rep(i,n) for(int i = 1;i <= n;i ++)
using namespace std;
const int N = 100005;
long long tag = 0;
long long a[N];
int main ()
{
    int n,m;
    scanf("%d%d",&n,&m);
    Rep(i,n)scanf("%I64d",&a[i]);
    Rep(i,m){
        int op;
        scanf("%d",&op);
        if(op == 1)
        {
            int pos;
            long long x;
            scanf("%d%lld",&pos,&x);
            a[pos] = x - tag;
        }
        else if(op == 2)
        {
            int opp ;
            scanf("%d",&opp);
            tag += opp;
        }
        else if(op == 3)
        {
            int pos ;
            scanf("%d",&pos);
            printf("%I64d\n",a[pos] + tag);
        }
    }
    return 0;
}

C:
题太长不想读。
D:
知道是一个很难写的模拟,不想写。
E:
开E,发现E不是很难。
给定n个元素组成的序列 {a1...an} ,对于所有的不重复不降子序列 {p1...pk} ,统计 pΠki=1pi
其中p为 {a1...an} 的不降子序列。
f[i] 表示以i结尾的总和。

f[i]=((f[j])+1)a[i]

然后需要减去一些不合法的东西,比如我们在更新树状数组的时候,实际上需要去掉上一个与 ai 相等的那个f值。
然后我们在最后询问的时候,我们只需要加上最后那个就成了。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define Rep(i,n) for(int i = 1;i <= n;i ++)
using namespace std;
const int N = 1000050;
const int Mod = 1e9 + 7;
const int nn = 1e6;
long long f[N]; 
int a[N], pre[N], cur[N];
long long t[N];
bool vis[N];
void Add(int i,long long val){for(int x = i;x <= nn;x += x & -x)t[x] = (t[x] + val) % Mod;}
long long Qry(int x)
{
    long long ans = 0;
    for(;x;x -= x & -x)ans = (ans + t[x]) % Mod;
    return ans % Mod;
}
int main ()
{
    int n;
    scanf("%d",&n);
    Rep(i,n)scanf("%d",&a[i]);
    Rep(i,n)
    {
        pre[i] = cur[a[i]], cur[a[i]] = i;
        f[i] = (Qry(a[i]) + 1ll) * a[i] % Mod;
        Add(a[i],(f[i] - f[pre[i]] + Mod) % Mod);
    }
    long long ans = 0;
    for (int i = n; i >= 1; -- i) if (!vis[a[i]]) ans = (ans + f[i]) % Mod, vis[a[i]] = true;
    printf("%I64d\n",ans % Mod);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值