这次的题有点难,慢慢补吧……
http://acm.hdu.edu.cn/search.php?field=problem&key=2018+Multi-University+Training+Contest+2&source=1&searchmode=source
1004
这道题就是一个比较典型的博弈,分析一下1怎么拿就行,最后答案就是先手必胜,Yes
1010
这道题的题意是给一个全排列,然后一个逆序对要花费x元,交换相邻的数一次要y元,然后问最小的花费。
因为一开始的逆序数是个常数,然后每次交换肯定会减少一个逆序对,那么只要求出 逆序数*min(x,y)
1007
题意就是维护一个数列,执行区间加一和查询的操作。
场上准备使用莫队算法乱搞,结果没写出来。
正解是使用线段树,维护一个最小值,初始值是B的值,当叶子节点的最小值变一的时候,给区间和加一,最后查询的时候查询和就行了。
为什么要这样做呢,首先查询的和是[ai/bi],ai的初始条件是0,每次加一的时候,要么会发生整除(1),也就是ai达到了bi的大小,要么是0,也就是ai没有达到bi的大小,每次发生整除的时候给sum加上一,然后把最小值重新赋值b的大小。
可以证明的是最后的时间复杂度是
#include <bits/stdc++.h>
#include <cstdio>
#include <algorithm>
using namespace std;
#define LL long long
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 111111;
LL add[maxn<<2];
LL sum[maxn<<2];
LL minv[maxn<<2];
LL b[maxn];
int n,m;
void PushUp(int rt)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
minv[rt] = min(minv[rt<<1],minv[rt<<1|1]);
}
void PushDown(int rt)
{
if (add[rt])
{
add[rt<<1] += add[rt];
add[rt<<1|1] += add[rt];
minv[rt<<1] -= add[rt];
minv[rt<<1|1] -= add[rt];
add[rt] = 0;
}
}
void build(int l,int r,int rt)
{
add[rt] = 0;
if (l == r)
{
minv[rt] = b[l];
sum[rt] = 0;
return;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
PushUp(rt);
}
void update(int L,int R,int l,int r,int rt)
{
if(minv[rt] > 1 && l ==L && r ==R)
{
add[rt]++;
minv[rt]--;
return;
}
if(l == r && minv[rt] == 1)
{
sum[rt] += 1;
add[rt] = 0;
minv[rt] = b[l];
return ;
}
PushDown(rt);
int m = (l + r) >> 1;
if(R <= m) update(L,R,lson);
else if(L > m) update(L,R,rson);
else update(L,m,lson),update(m+1,R,rson);
PushUp(rt);
}
LL query(int L,int R,int l,int r,int rt)
{
if (L <= l && r <= R)
{
return sum[rt];
}
if(minv[rt] <= 0) update(L,R,1,n,1);
PushDown(rt);
int m = (l + r) >> 1;
LL ret = 0;
if (L <= m)
ret += query(L, R, lson);
if (m < R)
ret += query(L, R, rson);
return ret;
}
int main()
{
char op[10];
while(scanf("%d%d",&n,&m) != EOF)
{
for(int i = 1; i<=n; i++)
{
scanf("%lld", &b[i]);
}
build(1,n,1);
for(int i = 1; i<=m; i++)
{
int a,b;
scanf("%s %d %d",op,&a,&b);
if(op[0] == 'a')
{
update(a,b,1,n,1);
}
else
{
printf("%lld\n",query(a,b,1,n,1));
}
}
}
return 0;
}