第二周
D - 敌兵布阵
线段树修改
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;
const int maxn = 1e5+5;
int a[maxn];
int tree[maxn*4];
void build(int p , int l , int r)
{
if( l == r )
{
tree[p] = a[l];
return ;
}
int mid = (l+r)>>1;
build(p * 2 , l , mid);
build(p * 2 + 1 , mid + 1 , r);
tree[p] = tree[p * 2]+tree[p * 2 + 1];
}
void add(int p , int l , int r , int x , int y)
{
if( l == r )
{
tree[p] += y;
return ;
}
int mid = (l+r)>>1;
if( x <= mid ){ add(p * 2 , l , mid , x , y); }
else { add(p * 2 + 1 , mid+1 , r , x , y); }
tree[p] = tree[p * 2] + tree[p * 2 + 1];
}
void sub(int p , int l , int r , int x , int y)
{
if( l == r )
{
tree[p] -= y;
return ;
}
int mid = (l+r)>>1;
if( x <= mid ){ sub(p * 2 , l , mid , x , y); }
else { sub(p * 2 + 1 , mid+1 , r , x , y); }
tree[p] = tree[p * 2] + tree[p * 2 + 1];
}
int query(int p , int l , int r , int x ,int y)
{
if( x <= l && r <= y )
{
return tree[p];
}
int mid = (l + r)>>1;
if( y <= mid )
{
return query(p * 2 , l , mid , x , y);
}
if( x > mid )
{
return query(p * 2 + 1 , mid + 1 , r , x , y);
}
else
{
return (query(p * 2 , l , mid , x, mid)+query(p * 2 + 1 , mid + 1 , r , mid+1 , y));
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t;
cin>>t;
while(t--)
{
memset(tree,-1,sizeof(tree));
memset(a,-1,sizeof(a));
int n;
cin>>n;
for(int i = 1 ; i <= n ; i++)
{
cin>>a[i];
}
build(1,1,n);
string s;int x,y;
static int ep = 1;
cout<<"Case "<<ep<<":"<<endl;
while(cin>>s)
{
if(s[0] == 'E')
{
break;
}
else if(s[0] == 'A')
{
cin>>x>>y;
add(1,1,n,x,y);
}
else if(s[0] == 'S')
{
cin>>x>>y;
sub(1,1,n,x,y);
}
else if(s[0] == 'Q')
{
cin>>x>>y;
cout<<query(1,1,n,x,y)<<endl;
}
}
ep++;
}
return 0;
}
E - I Hate It
线段树单点修改和查询最大值
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;
const int maxn = 200010;
int stu[maxn];
int tree[maxn<<2];
char op[4];
void build(int p , int l , int r )
{
if( l == r )
{
tree[p] = stu[l];
return ;
}
int mid = (l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
tree[p] = max(tree[p<<1],tree[p<<1|1]);
}
void update(int p , int l , int r ,int a ,int b)
{
if( l == r )
{
tree[p] = b;
return ;
}
int mid = (l+r)>>1;
if( a <= mid )
{
update(p<<1,l,mid,a,b);
}else
{
update(p<<1|1,mid+1,r,a,b);
}
tree[p] = max(tree[p<<1],tree[p<<1|1]);
}
int query(int p , int l , int r , int a , int b)
{
if( a <= l && r <= b )
{
return tree[p];
}
int mid = (l+r)>>1;
if( b <= mid )
{
return query(p<<1,l,mid,a,b);
}
if( a > mid )
{
return query(p<<1|1,mid+1,r,a,b);
}
else
{
return max(query(p<<1,l,mid,a,mid),query(p<<1|1,mid+1,r,mid+1,b));
}
}
int main()
{
int n,m;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(int i = 1 ; i <= n ; i++)
{
scanf("%d",&stu[i]);
}
build(1,1,n);
int a,b;
for(int i = 0 ; i < m ; i++)
{
scanf("%s%d%d",op,&a,&b);
if(op[0]=='U')
{
update(1,1,n,a,b);
}else
{
printf("%d\n",query(1,1,n,a,b));
}
}
}
return 0;
}
F - Just a Hook
区间修改查询总和
#include<iostream>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn = 1e5 + 5;
int sum[maxn<<2], lazy[maxn<<2];
void pushup(int rt) {//更新所有父节点的值
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void pushdown(int rt, int m) {//区间更改 时 标记子节点并更新子节点
if (lazy[rt]) {
lazy[rt << 1] = lazy[rt];
lazy[rt << 1 | 1] = lazy[rt];
sum[rt << 1] = lazy[rt] * (m - (m >> 1));
sum[rt << 1 | 1] = lazy[rt] * (m >> 1);
lazy[rt] = 0;
}
}
void build(int l, int r, int rt) {// 建立树
lazy[rt] = 0;//初始标记为0
if (l == r) { sum[rt] = 1; return; }//叶节点返回
int m = (l + r) >> 1;//向下建立子树
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
pushup(rt);//更新 父节点 边建立 边更新
}
void update(int L,int R, int c, int l, int r, int rt) {//更改区间 更改至c
if (L <= l && r<=R) { // l,r 树的区间 / L,R 需要的区间
lazy[rt] = c;
sum[rt]= (int)c*(r - l + 1);
return;
}
pushdown(rt,r-l+1);
int m = (l + r) >> 1;
if (L <= m) {
update(L, R, c, lson);
}
if (R > m) {
update(L, R,c, rson);
}
pushup(rt);
}
int main() {
ios::sync_with_stdio(false);
int t;
int a, b, c;
int k = 1;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
build(1, n, 1);
while (m--) {
cin >> a >> b >> c;
update(a, b, c, 1, n, 1);
} printf("Case %d: The total value of the hook is %d.\n", k++, sum[1]);
}
return 0;
}
A - Cancel the Trains
找相同的编号
#include<bits/stdc++.h>
using namespace std;
int d[105],l[105];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m,ans=0;
cin>>n>>m;
for(int i = 1;i <= n;i++)
cin>>d[i];
for(int j = 1;j <= m;j++)
cin>>l[j];
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++) {
if(d[i] == l[j])
ans++;
}
cout<<ans<<endl;
}
B - Tunnel Warfare
修改 区间合并
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
const int MAX = 500050;
int lmax[MAX], rmax[MAX], mmax[MAX];
void push_up(int node, int l, int r) {
lmax[node] = lmax[node << 1];
rmax[node] = rmax[node << 1 | 1];
int mid = (r + l) >> 1;
if (lmax[node] == mid - l + 1) lmax[node] += lmax[node << 1 | 1];
if (rmax[node] == r - mid) rmax[node] += rmax[node << 1];
mmax[node] = max(rmax[node << 1] + lmax[node << 1 | 1],
max(mmax[node << 1], mmax[node << 1 | 1]));
}
void build (int node, int l, int r) {
if (l == r) {
lmax[node] = rmax[node] = mmax[node] = 1;
} else {
int mid = (r + l) >> 1;
build(node << 1, l, mid);
build(node << 1 | 1, mid + 1, r);
push_up(node, l, r);
}
}
void update(int node, int l, int r, int loc, int s) {
if (l == r) {
if (l == loc) {
mmax[node] = lmax[node] =
rmax[node] = (s ? 0 : 1);
}
return;
}
int mid = (r + l) >> 1;
if (loc <= mid) update(node << 1, l, mid, loc, s);
else update(node << 1 | 1, mid + 1, r, loc, s);
push_up(node, l, r);
}
int query (int node, int l, int r, int loc) {
int mid = (r + l) >> 1;
if (mmax[node] == r - l + 1 || !mmax[node])
return mmax[node];
if (loc <= mid) {
if (loc >= mid - rmax[node << 1] + 1)
return query(node << 1, l, mid, loc) +
query(node << 1 | 1, mid + 1, r, mid + 1);
else return query(node << 1, l, mid, loc);
} else {
if (loc <= mid + 1 + lmax[node << 1 | 1] - 1)
return query(node << 1, l, mid, mid) +
query(node << 1 | 1, mid + 1, r, loc);
else return query(node << 1 | 1, mid + 1, r, loc);
}
}
int main() {
int n, m;
while(~scanf("%d%d", &n, &m)) {
stack<int> s;
build (1, 1, n);
while (m--) {
char op;
scanf(" %c", &op);
if (op == 'D') {
int loc;
scanf("%d", &loc);
update(1, 1, n, loc, 1);
s.push(loc);
} else if (op == 'Q') {
int loc;
scanf("%d", &loc);
printf("%d\n", query(1, 1, n, loc));
} else {
int loc = s.top();
s.pop();
update(1, 1, n, loc, 0);
}
}
}
return 0;
}
C - The Delivery Dilemma
先把外卖的时长排序,然后枚举比较就好,贪心。
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;
struct node{
long long a;
long long b;
}a[200003];
bool cmp(node x, node y)
{
return x.a < y.a;
}
long long sum[200003];
int main()
{
int t;
int n;
cin>>t;
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lld",&a[i].a);
for(int i=0;i<n;i++)
scanf("%lld",&a[i].b);
sort(a,a+n, cmp);
sum[0]=a[0].b;
for(int i=1;i<n;i++)
{
sum[i] = 0;
sum[i] = a[i].b + sum[i - 1];
}
long long ans = sum[n-1];
for(int i=0;i<n;i++)
{
ans = min(ans, max(a[i].a, sum[n-1] - sum[i]));
}
printf("%lld\n",ans);
}
return 0;
}