【洛谷】P4231 三步必杀
这好像是洛谷某次比赛题。难度:提高+/省选-(感觉难度标的太高了(逃)
这道题我想到了2种算法:1.差分 2.差分+树状数组
1.差分:
一个操作的过程是这样的:
a 0 0 0 s s+d s+2d ... e-2d e-d e 0 0 0 (原数组)
b 0 0 0 s d d ... d d d -e 0 0 (差分数组1)
c 0 0 0 s d-s 0 ... 0 0 0 -e-d e 0 (差分数组2)
一个如此诡异的操作,还是被神奇的差分数组消灭了。
所以对于每个操作,只需修改4个位置即可。
然后由c推出b推出a。
时间复杂度:O(m+n)
Code:
#include<bits/stdc++.h> using namespace std; const int MAXN = 1e7+10; #define LL long long #define rint register int int n,m,l,r; LL s,e,c[MAXN],b[MAXN],a[MAXN],mx,sum; int main() { scanf("%d %d",&n,&m); for (rint i = 1 ; i <= m ; i ++) { scanf("%d %d %lld %lld",&l,&r,&s,&e); int d = (e-s)/(r-l); c[l] += s; c[l+1] += d-s; c[r+1] += -e-d; c[r+2] += e; } LL t = 0; for (rint i = 1 ; i <= n ; i ++) { t += c[i]; b[i] = t; } t = 0; for (rint i = 1 ; i <= n ; i ++) { t += b[i]; mx = max(mx,t); sum ^= t; } printf("%lld %lld\n",sum,mx); return 0; }
1.差分+树状数组:
<有待填坑>
时间复杂度:O(mlog3n+logn)