1004 Game
题意:两个人玩游戏,一开始有n个数1~n,两人轮流操作,每轮选择一个没有被拿走的数,然后拿走它和他所有约数。拿光所有数的人获胜,给定n问先手必胜还是后手必胜。
解析:图片来自多校交流群,侵删。
1010 Swaps and Inversions
题意:有长为n的序列,序列中每个逆序要交y元钱,但是可以通过花x元钱来交换两个相邻的元素。问最小花费。
解析:注意到逆序对数=交换相邻元素需要交换的次数,那么输出 min(x,y)*逆序对个数 即可。这里用树状数组+离散化来求逆序数。
代码:
#include
using namespace std;
int a[100105],n,x,y;
long long ans;
struct AA
{
int x,num,now;
}pos[100105];//若数组开为100005会RE,很迷。
bool cmp(AA aa,AA bb)
{
return aa.x0)
{
s+=a[i];
i-=lowbit(i);
}
return s;
}
int main()
{
while(~scanf("%d%d%d",&n,&x,&y))
{
memset(a,0,sizeof(a));
ans=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&pos[i].num);
pos[i].x=i;
}
sort(pos+1,pos+1+n,cmpp);
int k=1;
pos[1].now=1;
for(int i=2;i<=n;i++)
{
if(pos[i].num==pos[i-1].num) pos[i].now=k;
else pos[i].now=++k;
}
sort(pos+1,pos+1+n,cmp);
for(int i=1;i<=n;i++)
{
add(pos[i].now);
ans+=i-sum(pos[i].now);
}
cout<
1007 Naive Operations
题意:有a,b两个串,b数组给定初值后是固定的,a数组初值为0;现有q次操作,操作有两种①.add l r:对[al,ar]区间内元素全部加一;②.query l r:求∑ l...r (⌊ai/bi⌋)
解析:显然当ai的add次数大于等于bi次时,才会对结果有影响,那么q次操作不会带来太多次的答案影响。
①.用线段树维护i位置还差多少次add能对答案产生一次影响,即i位置初始为bi,每次add使其减一,减到0时i位置即对答案贡献1,此时使答案数组c的i位置加1,然后将此处再设置为bi。这里判断哪个位置减到0了就是用线段树维护区间最小值来查询位置。
②.答案数组c用树状数组维护,方便区间查询。
代码(ayf大佬的代码):
#include
#include