Solution 标程太暴力惹QAQ 相当于是26棵线段树的说QAQ 不过我写了另一种写法,从大到小枚举每一个字母,标记字典序在这个字母之上的位置为1,每次都建一棵线段树,维护1的数量,即区间和. 修改操作就是先查询这个区间1的数量,排序本质上就是把1一起放在这个区间前面或后面,最后查询每个位置,如果为1并且没有被标记过,就标记成当前枚举的字母即可. 将看似复杂的问题转化为了简单的区间修改和查询QAQ 不过需要各种常数优化才能过QAQ Code #include<bits/stdc++.h>…
贪心思想.将a排序后,对于每一个a,找到对应的删除m个后最小的b,每次更新答案即可. 如何删除才是合法并且最优的?首先,对于排了序的a,第$i$个那么之前就应该删除前$i-1$个a对应的b.剩下$m-i+1$可以删,那么在剩下的b中查找第$m-i+2$小即可.每次做完就删除当前a对应的b. 注意离散化. 还有数组不要开大了.... #include<bits/stdc++.h> #define LL long long using namespace std; void read(int &a…
比较裸的$exgcd$的应用? $exgcd$可以算出在$x$和$y$分别是最小正整数时的解.注意在这里因为有$a(x+\frac{b}{d})+b(y-\frac{a}{d})=c$,$d=gcd(a,b)$,所以$\frac{b}{d}$和$\frac{a}{d}$一定是整数,所以最小$x$的整数解%的应该是$\frac{b}{d}$而不是$b$,$y$同理. 算出两种情况的最小整数解后,$x$为最小正数时$x$一直在加,$y$一直在减,所以$x$最小时$y$都为非正数,则无解.判$y$时同…
对于和规律或者数学有关的题真的束手无策啊QAQ 首先发现两个性质: 1.不管中间怎么碰撞,所有蚂蚁的相对位置不会改变,即后面的蚂蚁不会超过前面的蚂蚁或者落后更后面的蚂蚁. 2.因为所有蚂蚁速度一样,不管标号的话两只蚂蚁的碰撞相当于直接互相穿过,所以最初有多少蚂蚁方向向左,最后就有多少蚂蚁从左落下,向右同理. 总结一下又可以发现,比如有$cntl$只蚂蚁最初向左,$cntr$只蚂蚁最初向右,那么最后就是原位置的左边连续$cntl$只从左落下,原位置右边连续$cntr$只从右落下.我们将所有方向向左…
题意: 有n个国家投票,要得到一个国家的投票有一定的花费,如果给到一个国家的票同时也得到了它所有附属国的票,给出国家关系树,求至少得到m票的最小花费. 分析:基础树状背包,dp[i][j],以i为根的子树得j票的最小花费,该题输入有点恶心. #include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #…
鬼能想到是个贪心.明明觉得是树规啊..又完美爆零.. 从叶子节点往上更新,能保证最优解(这块想了半天). 证明:当你的子树上有能删的点而你不删时,可能会对子树的根节点有利,最好的情况是使子树根节点由不可删除变为可删除.但是,既然最终可能删一个点,还不如直接删现成能删的呢.. 用wei[]记录每个节点的权值(花数+儿子数),在更新结果时将权值更新即可. #include #include #include #include #include #include using namespace std…
[题目]#6396. 「THUPC2018」弗雷兹的玩具商店 / Toyshop [题意]给定一个长度为n的物品序列,每个物品有价值.不超过m的重量.要求支持以下三种操作:1.物品价值区间加减,2.物品重量区间加(超过m部分取模),3.区间物品求解容量为m的完全背包数组.\(n \leq 2*10^5,m \leq 60,Q \leq 3*10^4\). [算法]线段树+完全背包 显然,每个重量只需要保留价值最大的物品. 然后就很简单了,线段树每个维护一个数组c[x]表示重量x的最大价值,区间循…
题目链接 Black Nodes in Subgraphs 题目意思就是在一棵树中所有点标记为两种颜色(黑和白) 然后询问是否存在大小为X恰好有Y个黑点的连通块 这题我们可以用树型背包的方法 设$f[i][j][0]$为以$i$为根的子树中大小为$j$的连通块的黑点数目的最小值,该连通块必须经过$i$ $f[i][j][1]$为以$i$为根的子树中大小为$j$的连通块的黑点数目的最大值,该连通块必须经过$i$ 那么转移的时候有 $f[x][i + j][0] = min(f[x][i + j][…
http://acm.hdu.edu.cn/showproblem.php?pid=1561 题意:有n个点,容量为m,每个点有一个价值,还给出n条边,代表选第i个点之前必须先选ai,问最多的价值能取多少. 思路:每个点的花费是1,价值为w[i],然后直接按照树型背包写就行了. 还是老套路. dp[i][j] 表示以 i 为根结点的子树最大价值,然后像01背包一样枚举容量,再用一层循环去给子结点分配容量,最后回溯到根节点,根节点的值就是答案了. 因为是森林,所以添加一个0结点当作根,记得0结点是…
比较好想的一道题,直接用队列滑窗,因为扫一遍往队列里加东西时,改变的只有一个值,开桶储存好就行了! #include<bits/stdc++.h> using namespace std; int n, k, r; inline int min(int a, int b) { return a > b ? b : a; } inline int max(int a, int b) { return a > b ? a : b; } ], q[], cnt[], vis[], ned…