2019 multi-university hdu6

1005

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn = 2e3 + 50;
int b[maxn];
struct node{
	int x, y, w;
	node(){}
	node(int _x, int _y, int _w) :x(_x), y(_y), w(_w){}
}a[maxn];
struct tt{
	LL l, r, lx, rx, mx, sum;
}tree[maxn<<2];
inline void push_up(int);
inline void build(int rt, int l, int r){
	tree[rt].l = l; tree[rt].r = r;
	tree[rt].lx = tree[rt].rx = tree[rt].sum = tree[rt].mx = 0;
	if (l == r){
		return;
	}
	int mid = (l + r) >> 1;
	build(rt << 1, l, mid);
	build(rt << 1 | 1, mid + 1, r);
	//push_up(rt);
}
inline void push_up(int rt){
	tree[rt].lx = max(tree[rt << 1].lx, tree[rt << 1 | 1].lx + tree[rt << 1].sum);
	tree[rt].rx = max(tree[rt << 1 | 1].rx, tree[rt << 1].rx + tree[rt << 1 | 1].sum);
	tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
	tree[rt].mx = max(max(tree[rt << 1].mx, tree[rt << 1 | 1].mx), tree[rt << 1].rx + tree[rt << 1 | 1].lx);
}
inline void insert(int rt,int pos,LL w){
	if (tree[rt].l == tree[rt].r){
		tree[rt].mx=tree[rt].lx = tree[rt].rx = tree[rt].sum = tree[rt].mx +w;
		return;
	}
	int mid = (tree[rt].l + tree[rt].r) >> 1;
	if (pos <= mid)insert(rt<<1,pos,w);
	else insert(rt<<1|1,pos,w);
	push_up(rt);
}
inline LL query(){
	return tree[1].mx;
}
int cmp(node a, node b){
	if (a.x == b.x){
		return a.y < b.y;
	}
	return a.x < b.x;
}
int main(){
	int t;
	cin >> t;
	while (t--){
		int n; int x, y, w;
		cin >> n;
		for (int i = 0; i < n; i++){
			cin >> x >> y >> w;
			a[i].x = x; a[i].y = y;
			a[i].w = w; b[i] = y;
		}
		sort(b, b + n);
		int k = unique(b, b + n) - b;
		for (int i = 0; i < n; i++){
			int temp = lower_bound(b, b + k, a[i].y) - b;
			a[i].y = temp+1;
		}
		sort(a, a + n, cmp); long long ans = 0;
		for (int i = 0; i < n; i++){
			if (i != 0 && a[i].x == a[i - 1].x)
				continue;
			build(1, 1, k);
			for (int j = i; j < n; j++){
				if (j != i && a[j].x != a[j - 1].x)
					ans = max(ans, query());
				insert(1,a[j].y,a[j].w);
			}
			ans = max(ans, query());
		}
		cout << ans << endl;
		
	}
}

1002

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 5e4 + 100;
int a[maxn], book[maxn], pos[maxn], ans[maxn],dp[maxn];
int tot[maxn];
int n;
void find(){
	for (int i = 0; i < n; i++)
	{
		dp[i] = book[i] = inf;
		tot[i] = -1;
	}
	int maxnl = 0;
	for (int i = 0; i < n; i++)
	{
		if (a[i] != inf)
		{
			int p = lower_bound(dp, dp + n, a[i]) - dp;
			if (dp[p] == inf)
			{
				tot[i] = p;
				dp[p] = a[i];
				maxnl = max(maxnl, p);
			}
			else
			{
				tot[i] = p;
				dp[p] = a[i];
			}
		}
	}
	for (int i = n - 1; i >= 0; i--)
	{
		if (maxnl < 0)break;
		if (tot[i] == maxnl)
		{
			maxnl--;
			book[i] = 1;
		}
	}
}
int main(){
	int t;
	cin >> t;
	while (t--)
	{
		cin >> n;
		for (int i = 0; i < n; i++) cin >> a[i];
		for (int i = 0; i < n; i++) {
			cin >> pos[i]; pos[i]--;
		}
		find();
		for (int i = n - 1; i >= 0; i--)
		{
			ans[i] = lower_bound(dp, dp + n, inf) - dp;
			if (book[pos[i]] == 1)
			{
				a[pos[i]] = inf;
				find();
			}
			else a[pos[i]] = inf;
		}
		for (int i = 0; i < n; i++)
			if (i == n - 1)
				cout << ans[i] << endl;
			else
				cout << ans[i] << " ";
	}
}

1006

暴力的暴力叫暴力
将 |xi − xe| + |yi − ye| 的绝对值拆掉,则每个点 (xi, yi) 会将平面分割成 4 个部分,每个部
分里距离的表达式没有绝对值符号,一共 O(n2) 个这样的区域(实际上应该是(n+1)2个).
枚举每个区域,计算该区域中可能的终点数量。注意到 lcm(2, 3, 4, 5) = 60,所以只需要枚
举 xe 和 ye 模 60 的余数,O(n) 判断是否可行,然后 O(1) 计算该区域中有多少这样的点即可.
时间复杂度为 O(602n3).

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=15,K=60;
int Case,n,m,x,y,i,j,ca,cb,a[N],b[N];long long ans;
struct E{int x,y,k,t;}e[N];
inline int abs(int x){return x>0?x:-x;}
inline bool check(int x,int y){
  for(int i=0;i<n;i++)if((abs(x-e[i].x)+abs(y-e[i].y))%e[i].k!=e[i].t)return 0;
  return 1;
}
inline int cal(int l,int r){
  r-=l+1;
  if(r<0)return 0;
  return r/K+1;
}
int main(){
  scanf("%d",&Case);
  while(Case--){
    scanf("%d%d",&n,&m);
    a[ca=1]=b[cb=1]=m+1;
    for(i=0;i<n;i++){
      scanf("%d%d%d%d",&e[i].x,&e[i].y,&e[i].k,&e[i].t);
      a[++ca]=e[i].x;
      b[++cb]=e[i].y;
    }
    sort(a+1,a+ca+1);
    sort(b+1,b+cb+1);
    ans=0;
    for(i=0;i<ca;i++)
		if(a[i]<a[i+1])
			for(j=0;j<cb;j++)
				if(b[j]<b[j+1])
					for(x=0;x<K;x++)
						for(y=0;y<K;y++)
							if(check(a[i]+x,b[j]+y))
								ans+=1LL*cal(a[i]+x,a[i+1])*cal(b[j]+y,b[j+1]);
    printf("%lld\n",ans);
  }
}

你可能感兴趣的:(HDU,多校)