对局匹配

直接贪心

#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
void makedata() {
freopen("input.txt", "w", stdout);
cout << << endl; for(int i = ; i < ; i++) cout << << ' '; fclose(stdout);
} int a[]; int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
//makedata();
std::ios::sync_with_stdio(), cin.tie();
int n, k;
cin >> n >> k; for(int i = ; i < n; i++) cin >> a[i]; sort(a, a + n);
int ptr = , ans = ; while(ptr < n) {
if(ptr + < n && a[ptr + ] - a[ptr] <= k) {
ans++;
ptr += ;
} else ptr++;
} cout << ans << endl;
return ;
}

稀疏矩阵乘积

对应关系别搞乱就行了

#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
#include<set>
#include <list>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII; int x[], y[], w[], b[][], c[][]; int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
std::ios::sync_with_stdio(), cin.tie();
int n, p, q;
int xx, yy, ww;
cin >> n >> p >> q;
for (int i = ; i < p; i++)cin >> x[i] >> y[i] >> w[i];
memset(b, , sizeof(b));
for (int i = ; i < q; i++) {
cin >> xx >> yy >> ww;
b[xx][yy] = ww;
}
memset(c, , sizeof(c));
for (int i = ; i < p; i++) {
for (int j = ; j <= n; j++) {
c[x[i]][j] += w[i] * b[y[i]][j];
}
}
for (int i = ; i <= n; i++) {
for (int j = ; j <= n; j++) {
if (c[i][j] != ) cout << i << ' ' << j << ' ' << c[i][j] << endl;
}
}
return ;
}

树上的等差数列

首先随便以某一个节点为根把树建起来。树上的一条路径可以看成是从某一个节点出发,在树结构上上升到某一个祖先节点,再下降到一个后代节点。记录father[x]为x节点的父节点,dep[x]为前两项为a[father[x]],a[x]的等差数列沿树结构向下最多能走的深度。枚举这个最高点r,把它的子节点按权值分类,枚举所有能构成等差数列的组合a1,a[r],a2,找到权值分别为a1和a2的子节点中dep值最大的点(且这两个点不为同一个点),那么产生了一个局部的最长等差数列l(a1)+1+l(a2),选出其中最大的输出。

#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
#include<set>
#include <list>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII; map<int, VI> mp[];
int a[], father[], dep[];
VI G[]; void build(int x, int fa) {
father[x] = fa;
for (int i = ; i < G[x].size(); i++) {
int u = G[x][i];
if (u == fa) continue;
auto it = mp[x].find(a[u]);
if (it == mp[x].end()) mp[x][a[u]] = VI();
mp[x][a[u]].push_back(u);
build(u, x);
}
}
void calc(int x) {
if (dep[x] != ) return;
int d = a[father[x]] - a[x];
int aa = a[x] - d;
auto it = mp[x].find(aa);
if (it == mp[x].end()) {
dep[x] = ;
return;
}
int tmp = ;
for (int i = ; i < (*it).second.size(); i++) {
int u = (*it).second[i];
calc(u);
if (dep[u] + > tmp) tmp = dep[u] + ;
}
dep[x] = tmp;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
std::ios::sync_with_stdio(), cin.tie();
int n;
cin >> n;
for (int i = ; i <= n; i++) cin >> a[i];
for (int i = ; i < n; i++) {
int u, v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
build(, );
memset(dep, , sizeof(dep));
for (int i = ; i <= n; i++) calc(i);
int ans = ;
for (int i = ; i <= n; i++) {
for (auto itl = mp[i].begin(); itl != mp[i].end(); itl++) {
int lval = (*itl).first, ldep = , ldot = ;
for (int j = ; j < (*itl).second.size(); j++) {
if (dep[(*itl).second[j]] > ldep) {
ldep = dep[(*itl).second[j]];
ldot = (*itl).second[j];
}
}
int rval = * a[i] - lval, rdep = , rdot = ;
auto itr = mp[i].find(rval);
if (itr == mp[i].end()) {
if (ldep + > ans) ans = ldep + ;
continue;
}
for (int j = ; j < (*itr).second.size(); j++) {
if (dep[(*itr).second[j]] > rdep && (*itr).second[j] != ldot) {
rdep = dep[(*itr).second[j]];
rdot = (*itr).second[j];
}
}
if (ldep + + rdep > ans) ans = ldep + + rdep;
}
}
cout << ans << endl;
return ;
}

翻转字符串

可以用Splay树实现反转操作。首先根据整个字符串建树,对于每次操作(l,r),首先把l左边的字符旋转到根节点上,此时(l,r)位于根节点的右子树上;然后把r右边的字符旋转到根节点的右子树的树根,这样一来,就得到了只由(l,r)构成的一棵子树:根节点的右子树的左子树,对其添加一个lazy标记,最后对树进行一个前序遍历即可。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
using namespace std;
const int maxLength = ;
class Node{
public:
Node *child[];
char value;
int size;
bool flip;
Node(char c) :value(c), size(), flip(false){
child[] = child[] = NULL;
}
int getPosition()const{
return child[] ? child[]->size + : ;
}
void maintain();
void pushDown();
};
void Node::maintain(){
size = ;
if (child[]){
size += child[]->size;
}
if (child[]){
size += child[]->size;
}
}
void Node::pushDown(){
if (flip){
swap(child[], child[]);
for (int i = ; i < ; i++){
if (child[i]){
child[i]->flip ^= ;
}
}
flip = false;
}
}
class SplayTree{
public:
Node *root;
SplayTree(char *a, int n);
void build(Node *&node, char *begin, char *end);
void rotate(Node *&node, int direction);
void splay(Node *&node, int position);
void reverse(int begin, int end);
void traverse(Node *u);
void traverse();
};
SplayTree::SplayTree(char *a, int n){
build(root, a, a + n - );
}
void SplayTree::build(Node *&node, char *begin, char *end){
if (begin > end){
return;
}
char *middle = begin + (end - begin >> );
node = new Node(*middle);
build(node->child[], begin, middle - );
build(node->child[], middle + , end);
node->maintain();
} void SplayTree::rotate(Node *&node, int direction){
Node *child = node->child[direction ^ ];
node->child[direction ^ ] = child->child[direction];
child->child[direction] = node;
node->maintain();
child->maintain();
node = child;
}
void SplayTree::splay(Node *&node, int position){
node->pushDown();
if (node->getPosition() != position){
int d = node->getPosition() < position;
Node *node2 = node->child[d];
position -= d ? node->getPosition() : ;
node2->pushDown();
if (node2->getPosition() != position){
int d2 = node2->getPosition() < position;
position -= d2 ? node2->getPosition() : ;
splay(node2->child[d2], position);
if (d == d2){
rotate(node, d ^ );
}
else{
rotate(node->child[d], d);
}
}
rotate(node, d ^ );
}
}
void SplayTree::reverse(int begin, int end){
splay(root, begin);
splay(root->child[], end - begin + );
root->child[]->child[]->flip ^= ;
}
void SplayTree::traverse(Node *u){
if (!u){
return;
}
u->pushDown();
traverse(u->child[]);
if (u->value){
printf("%c", u->value);
}
traverse(u->child[]); }
void SplayTree::traverse(){
traverse(root);
}
int main(){
char s[maxLength] = "";
while (~scanf("%s", s + )){
int n = strlen(s + );
SplayTree splay(s, n + );
int k;
scanf("%d", &k);
for (int i = ; i < k; i++){
int begin, end;
scanf("%d%d", &begin, &end);
splay.reverse(begin + , end + );
}
splay.traverse();
printf("\n");
}
return ;
}

[Offer收割]编程练习赛42的更多相关文章

  1. hihocoder [Offer收割]编程练习赛4

    描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, ... AN元.并且如果消费总计满X元,还能享受优惠.小Ho是一个不薅羊毛不舒服斯基的人,他希望 ...

  2. hihocoder [Offer收割]编程练习赛61

    [Offer收割]编程练习赛61 A:最小排列 给定一个长度为m的序列b[1..m],再给定一个n,求一个字典序最小的1~n的排列A,使得b是A的子序列. 贪心即可,b是A的子序列,把不在b中的元素, ...

  3. [Offer收割]编程练习赛46

    [Offer收割]编程练习赛46赛后题解 A.AEIOU 分析

  4. ACM学习历程—Hihocoder [Offer收割]编程练习赛1

    比赛链接:http://hihocoder.com/contest/hihointerview3/problem/1 大概有一个月没怎么打算法了.这一场的前一场BC,也打的不是很好.本来Div1的A和 ...

  5. HihoCoder1670 : 比赛日程安排([Offer收割]编程练习赛41)(模拟)

    描述 H国编程联赛中有N只队伍,编号1~N. 他们计划在2018年一共进行M场一(队)对一(队)的比赛. 为了让参赛队员能得到充分的休息,联赛组委会决定:每支队伍连续两场比赛之间至少间隔一天.也就是如 ...

  6. HihoCoder1642 : 三角形面积和([Offer收割]编程练习赛37)(求面积)(扫描线||暴力)(占位)

    描述 如下图所示,在X轴上方一共有N个等腰直角三角形.这些三角形的斜边与X轴重合,斜边的对顶点坐标是(Xi, Yi). (11,5) (4,4) /\ /\(7,3) \ / \/\/ \ / /\/ ...

  7. [Offer收割]编程练习赛48

    题目1 : 折线中点 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定平面上N个点P1, P2, ... PN,将他们按顺序连起来,形成一条折线. 请你求出这条折线的 ...

  8. [Offer收割]编程练习赛3 - 题目3 : 智力竞赛

    智力竞赛 Problem's Link ---------------------------------------------------------------------------- Mea ...

  9. [Offer收割]编程练习赛5-1 小Ho的防护盾

    #1357 : 小Ho的防护盾 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho的虚拟城市正在遭受小Hi的攻击,小Hi用来攻击小Ho城市的武器是一艘歼星舰,这艘歼星 ...

随机推荐

  1. 数据迁移 Migration

  2. 【剑指Offer】40、数组中只出现一次的数字

      题目描述:   一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度为O(n),空间复杂度为O(1).   解题思路:   这道题目相对比较难 ...

  3. Network-Flow

    //Created by pritry int graph[MAX][MAX]; //原图 int source; //起点,这里为0 int sink; //终点,这里为n-1 int e[MAX] ...

  4. nyoj24-素数 距离问题

    素数距离问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度.如果左右有等距离长度素数 ...

  5. Ubuntu Server下docker实战 02: docker进阶配置

    在上一篇文章里<Ubuntu Server下docker实战 01: 安装docker>,我们已经把docker安装起来了,并运行了一个hello-world 这一篇,我们继续讲进阶配置. ...

  6. Git 基础教程 之 创建与合并分支

  7. dubbo客户端初始化问题

    背景:工作中遇到了调用dubbo服务的场景,项目不是spring项目,我只想简单的调用服务端的接口,不想加入那么多配置. 在服务对接中,遇到调用dubbo服务的场景.按照公司的框架给的开发文档,要加配 ...

  8. 0926mysql中MRR的用法

    转自 http://blog.itpub.net/22664653/viewspace-1673682  [MySQL]MySQL5.6新特性之Multi-Range Read 2015-05-27 ...

  9. 【ACM】hdu_1004_Let the Balloon Rise

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  10. HDU 4518

    整理一下思路,明天再写... 这道题,其实就是求包含大于10的斐波那切数字的第K(K是斐波那契数)个数.注意到斐波那契数的爆炸性增长,所以在范围 内的符合要求的F数并不多吧.比如求第K个F数,那么,前 ...