A - Secret of Chocolate Poles
dbq,我没想到dp,我还在找规律,组合数之类的
B - Parallel Lines
计算几何,不是我写的
DFS 明天补叭
C - Medical Checkup
没开longlong挂了好多次
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<unordered_map>
#include<string>
#include<map>
#include<string.h>
#define inf 2e9
using namespace std;
const int maxn = 1e5 + 5;
int a[maxn],n,ans[maxn];
long long t;
int main() {
cin >> n >> t;
for (int i = 1;i <= n;i++)cin >> a[i];
int cur_record = a[1];
long long cur_sum = 0;
for (int i = 1;i <= n;i++) {
cur_sum += a[i];
cur_record = max(cur_record, a[i]);
//i开始往前排队的时候,最慢的人已经排到的位置
//+pos(1)
long long pos = 1;
if(t >= cur_sum)
pos = long long((t - cur_sum)/cur_record + 2);
cout << pos << endl;
}
return 0;
}
学了差分数组(一直被这个名字劝退,真的好奇怪)
差分数组
f[i]=a[i]-a[i-1],那么每个数组元素a[i]=f[1]+f[2]+…+f[i]=a[1]+a[2]-a[1]+a[3]-a[2]+…a[i]-a[i-1] = a[i]
通过差分数组可以求前缀和 sum[i]=a[1]+a[2]+…+a[i] = f[1]+ f[1]+f[2]+f[1]+f[2]+f[3]+…=(i)f[1]+(i-1)f[2]+…+f[i] = sigma_k=1 ^(i) (i-k+1) * f[k];
用途:
差分数组可以快速处理区间加减操作和前缀和。
- 处理加减操作时,假设[L,R]上的每一个数组元素+=k,则只需要在前缀数组f[L]处+=k,在f[R+1]-=k,就可,
- 前缀和操作如上。
先熟悉一下
洛谷P3948 第一次在洛谷见到这么多数据的题hh
差分模板题
#include"pch.h"
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <cmath>
#include <vector>
#include <queue>
#include <string>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define INF 0x3f3f3f3f
#define sz sizeof
#define mk make_pair
using namespace std;
long long n, opt, minn, maxn,mod;
long long f[100005],p[100005];
long long work(long long l, long long r) {
long long res = 0,t=0;
//求出a[l-1]的值
for (int i = 1;i < l;i++) {
t += f[i];
}
for (int i = l;i <= r;i++) {
t += f[i];//L_R真实区间中的每一个值
if (t *i%mod >= minn && t * i%mod <= maxn) {
res++;
}
}
return res;
}
void prepare() {
long long tmp=0, t = 0;
bool flag = false;
for (int i = 1;i <= n;i++) {
t += f[i];
flag = false;
if (t*i%mod >= minn && t*i%mod <= maxn) {
flag = true;
}
p[i] = p[i - 1] + flag;
}
return;
}
int main() {
cin >> n >> opt >> mod >> minn >> maxn;
for (int i = 1;i <= opt;i++) {
char a;cin >> a;
long long l, r;
if (a == 'A') {
long long x; cin >> l >> r >> x;
f[l] += x;f[r+1] -= x;
}
else {
cin >> l >> r;
long long ans = work(l, r);
cout << ans << endl;
}
}
long long fia;cin >> fia;
prepare();
for (int i = 1;i <= fia;i++) {
long long l, r;cin >> l >> r;
cout << p[r] - p[l-1] << endl;
}
return 0;
}
补题
I Starting a Scenic Railroad Service
两种策略:
1.自由选择-由于选择顺序不确定
ans1:代表最差情况,是区间相交数的最大值。
玄妙的结论:
与一个区间相交的区间个数 = 右端点前左端点的个数 - 左端点前右端点的个数
好神奇啊啊啊啊啊啊啊啊啊啊这样相离的会被消掉诶 好东西,MARK
2.安排-是使得座位数最少的最优策略
所求ans2是指某个时刻(车站)上人数的最大值,
用区间代表,也就是区间存在重叠时,这些人同时在车站。(下面是废话,一波解释)
这种情况,不能够通过安排座位减少座位总数。(使用sum数组表示人数,
记录一个旅客的起点、终点时,使用差分数组操作;求解时先复原数组,直接求最大值即可)
所以:ans1=max(与区间i交叉的区间个数总和)(i=1,2,…n) //每个站的区间交叉最大值
ans2 =max(sum[i]) //每个站 的人数 最大值
代码还在running,可我已经感觉被掏空orz 再失眠会死吗1551
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <cmath>
#include <vector>
#include <queue>
#include <string>
#include <bitset>
#include <unordered_map>
#include <unordered_set>
#define INF 0x3f3f3f3f
#define sz sizeof
using namespace std;
const int maxn = 2e5 + 10;
int n,ans1,ans2;
struct Line {
int L, R;
}l[maxn];
//记录起点个数,终点个数,人数
int st[maxn], ed[maxn], sum[maxn];
int main() {
cin.tie(0);
ios::sync_with_stdio(0);
cin >> n;
for (int i = 1;i <= n;i++) {
cin >> l[i].L >> l[i].R;
//计数操作,就不要遍历了 这就是差分数组的好处
st[l[i].L]++; ed[l[i].R]++;
//这里就是--的操作 因为这里是左闭右开,所以不用+1
sum[l[i].L]++;sum[l[i].R]--;
}
//恢复原数组
for (int i = 1;i <= maxn;i++) {
st[i] += st[i - 1];
ed[i] += ed[i - 1];
sum[i] += sum[i - 1];
}
for (int i = 1;i <= n;i++) {
//右端点前面左端点的个数-左端点前右端点的个数
ans1 = max(ans1, st[l[i].R-1] - ed[l[i].L]);
}
for (int i = 1;i < maxn;i++) {
ans2 = max(ans2, sum[i]);
}
cout << ans1 << " " << ans2 << endl;
return 0;
}
F - Pizza Delivery
图论 都是dalao,佩服佩服