颓废

颓废啦,文化课又爆炸啦。

继续刷水题啦

BZOJ1452 [JSOI2009]Count

震惊,JSOI竟有这种傻逼题!

#prag\
ma GCC optimize("O3")
#include <cstdio>
#include <cstring>
#define lowbit(x) (x & -x)
const int MAXN = 300;
using namespace std;
 
int n, m;
 
class Bit {
    public :
        Bit() {memset(c, 0, sizeof(c));}
        void update(int x, int y, int num, int val);
        int GetSum(int x, int y, int num);
        int query(int a, int b, int x, int y, int num);
    private :
        int c[MAXN + 5][MAXN + 5][100 + 5];
}T;
 
void Bit::update(int x, int y, int num, int val) {
    for (int i = x; i <= n; i += lowbit(i))
        for (int j = y; j <= m; j += lowbit(j))
            c[i][j][num] += val;
}
 
int Bit::GetSum(int x, int y, int num) {
    int ret = 0;
     
    for (int i = x; i; i -= lowbit(i))
        for (int j = y; j; j -= lowbit(j))
            ret += c[i][j][num];
     
    return ret;
}
 
int Bit::query(int a, int b, int x, int y, int num) { 
//  cout << '*' << a << ' ' << b << ' ' << x << ' ' << y << ' ' << GetSum(x, y, num) << endl;
    return GetSum(x, y, num) - GetSum(a - 1, y, num) - GetSum(x, b - 1, num) + GetSum(a - 1, b - 1, num);
}
 
int arr[MAXN + 5][MAXN + 5];
 
int main() {    
	scanf("%d%d", &n, &m);
	    
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            scanf("%d", &arr[i][j]), T.update(i, j, arr[i][j], 1);
     
    int q; scanf("%d", &q);
     
    while (q--) {
        int opt, a, b, x, y, num; scanf("%d%d%d", &opt, &a, &b);
         
        switch(opt) {
            case 1 : {
                scanf("%d", &num), T.update(a, b, arr[a][b], -1);
                arr[a][b] = num, T.update(a, b, arr[a][b], 1);  
                break;
            }
            case 2 : scanf("%d%d%d", &x, &y, &num), printf("%d\n", T.query(a, x, b, y, num)); break;
        }
    }
     
    return 0;
}

BZOJ3343 教主的魔法

太经典的分块了,一直没做。

#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>
const int MAXN = 1e6;
using namespace std;

inline int read() {
	int x = 0, w = 1; char c = ' ';
	while (c < '0' || c > '9') {c = getchar(); if (c == '-') w = -1;}
	while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
	return x * w;
}

int n, block, num, a[MAXN + 5], l[MAXN + 5], r[MAXN + 5], delta[MAXN + 5], belong[MAXN + 5];
vector < int > V[MAXN + 5];

void build() {
	block = sqrt(n), num = n / block;
	if (n % block) ++num;
	
	for (int i = 1; i <= num; ++i) 
		l[i] = (i - 1) * block + 1, r[i] = i * block;
	r[num] = n;
	
	for (int i = 1; i <= n; ++i)
		belong[i] = (i - 1) / block + 1, V[belong[i]].push_back(a[i]);
	
	for (int i = 1; i <= num; ++i)
		sort(V[i].begin(), V[i].end());
}

void rebuild(int x) {
	V[x].clear();
	
	for (int i = l[x]; i <= r[x]; ++i)
		V[x].push_back(a[i]);
	
	sort(V[x].begin(), V[x].end());
}

void update(int x, int y, int val) {
	if (belong[x] == belong[y]) 
		for (int i = x; i <= y; ++i)	
			a[i] += val;
	else {
		for (int i = x; i <= r[belong[x]]; ++i)
			a[i] += val;
		
		for (int i = belong[x] + 1; i < belong[y]; ++i)
			delta[i] += val;
		
		for (int i = l[belong[y]]; i <= y; ++i)
			a[i] += val;
	}
	
	rebuild(belong[x]), rebuild(belong[y]);
}

inline int calc(int x, int val) {
	return V[x].size() - (lower_bound(V[x].begin(), V[x].end(), val) - V[x].begin());
}

int query(int x, int y, int val) {
	int ret = 0;
	
	if (belong[x] == belong[y])	{
		for (int i = x; i <= y; ++i)
			if (a[i] + delta[belong[i]] >= val) ++ret;
	}
	else {
		for (int i = x; i <= r[belong[x]]; ++i)
			if (a[i] + delta[belong[i]] >= val) ++ret;
			
		for (int i = belong[x] + 1; i < belong[y]; ++i)
			ret += calc(i, val - delta[i]);
			
		for (int i = l[belong[y]]; i <= y; ++i)
			if (a[i] + delta[belong[i]] >= val) ++ret;
	} 
	
	return ret;
}

int main() {
	n = read(); int q = read();
	
	for (int i = 1; i <= n; ++i) 
		a[i] = read();
	
	build();
	
	while (q--) {
		char c = getchar(); while (c != 'A' && c != 'M') c = getchar();
		int x = read(), y = read(), val = read();
		
		switch(c) {
			case 'M' : update(x, y, val); break;
			case 'A' : printf("%d\n", query(x, y, val)); break;
		}
	}
	
	return 0;
}

[HNOI2003]激光炸弹

这种题还算省选题?

二维前缀和水过。

卡内存有毒。

#include <iostream>
#include <cstdio>
#define min(a, b) (a < b ? a : b)
#define max(a, b) (a < b ? b : a)
const int MAXN = 5005;
using namespace std;

inline int read() {
	int x = 0, w = 1; char c = ' ';
	while (c < '0' || c > '9') {c = getchar(); if (c == '-') w = -1;}
	while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
	return x * w;
}

short a[MAXN + 5][MAXN + 5];
int S[MAXN + 5][MAXN + 5];

int main() {
	int n = read(), r = read(), x, y, num; int Ans = 0;
	
	for (int i = 1; i <= n; ++i) {
		x = read(), y = read(), num = read();
		a[x + 1][y + 1] = num;
	}
	
	for (int i = 1; i <= MAXN + 1; ++i)
		for (int j = 1; j <= MAXN + 1; ++j)
			S[i][j] = S[i - 1][j] + S[i][j - 1] - S[i - 1][j - 1] + a[i][j];
	
	for (int i = 1; i <= MAXN + 1; ++i)
		for (int j = 1; j <= MAXN + 1; ++j) {
			x = i + r - 1, y = j + r - 1;
			if (x > MAXN + 1 || y > MAXN + 1) continue;
			Ans = max(Ans, S[x][y] - S[i - 1][y] - S[x][j - 1] + S[i - 1][j - 1]);
		}
	
	printf("%d\n", Ans);
	
	return 0;
}	

BZOJ1614 [Usaco2007 Jan]Telephone Lines架设电话线

二分求极值+最短路

二分边长,权值大于mid边权为1,小于或等于则为0。

跑一遍Dijkstra,看看最短路有没有到达mid,如果超过了,那么就满足题意。

经典好题

#include <iostream>
#include <cstdio>
#include <cstring> 
#include <queue>
const int MAXN = 1000;
const int INF = 1000000;
using namespace std;

inline int read() {
	int x = 0, w = 1; char c = ' ';
	while (c < '0' || c > '9') {c = getchar(); if (c == '-') w = -1;}
	while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
	return x * w;
}

struct Edge {
	int to, w, nxt;
};

struct Node {
	int id, num;
	bool operator < (const Node &a) const {
		return num > a.num;
	}
	Node(int _id, int _num) : id(_id), num(_num) {}
};

class Graph {
	public :
		Graph() {memset(head, -1, sizeof(head)), tot = 0, memset(dist, 0x3f, sizeof(dist)), memset(vis, false, sizeof(vis));}
		void add(int u, int v, int w) {
			edge[tot] = (Edge) {v, w, head[u]}, head[u] = tot++;
		}
		int Dijkstra(int s, int t);
	private :
		int head[MAXN + 5], tot, dist[MAXN + 5];
		Edge edge[20000 + 5];
		bool vis[MAXN + 5];
		priority_queue < Node > Q;
};

int Graph::Dijkstra(int s, int t) {

	Q.push(Node(s, 0)), dist[s] = 0;

	while (!Q.empty()) {
		Node u = Q.top(); Q.pop();
		if (vis[u.id]) continue;
		
		for (int i = head[u.id]; ~i; i = edge[i].nxt) {
			int v = edge[i].to, w = edge[i].w;
			if (u.num + w < dist[v]) {
				dist[v] = w + u.num;
				Q.push(Node(v, dist[v]));
			}
		}
		
		vis[u.id] = true;
	}
	
	return dist[t];
}

struct Query {
	int u, v, w;
}q[20000 + 5];

int n, m, k, Ans = -1;

bool check(int mid) {
	Graph G; 
	
	for (int i = 1; i <= m; ++i) {
		int u = q[i].u, v = q[i].v, w = q[i].w > mid;
		
		G.add(u, v, w), G.add(v, u, w);
	}
	
	return G.Dijkstra(1, n) <= k; 
}

int main() {
	n = read(), m = read(), k = read();
	
	for (int i = 1; i <= m; ++i) {
		int u = read(), v = read(), w = read();
		q[i] = (Query) {u, v, w};
	}
	
	int l = 0, r = INF;
	
	while(l <= r) {
		int mid = l + r >> 1;
		
		if (check(mid))
			r = mid - 1, Ans = mid;
		else 
			l = mid + 1;
	}
	
	printf("%d\n", Ans);
	
	return 0;
}	
posted @ 2018-03-27 19:19  23forever  阅读(147)  评论(0编辑  收藏  举报