[log] lightOJ 刷题

来源:互联网 发布:域名紧急更换通知 编辑:程序博客网 时间:2024/05/08 04:01

数据结构

loj 1188 - Fast Queries

题意:
N <= 1e5, 1 <= ai <= 1e9
然后 m 个询问 [l, r], m <= 1e5
问你 [l, r] 中有数的种类是多少
思路:
对每一种数,只需要存他最新的位置就行了。
从1到n扫一遍,对ai先把其旧的位置删除,然后i位置加1,可以用BIT维护。同时回答每个询问。
时间复杂度: O(n+m)
这道题有个类似的:Hackerrank Coloring Tree

动态规划

loj 1073 - DNA Sequence

题意:
n个只含A,G,C,T的string。求一个长度最短的串使得给出的字符串都是其子串。相同长度的输出字典序最小的。
思路:
压位dp 注意处理一个string为另一个string的子串的情况
先dp求出最短长度
利用dp时保存的状态,标记出最优解的转移路线
然后dfs 求出字典序最小的解
dfs的时候 要同时判断长度, 因为可能沿没有标记的路线进行转移!
这一点很重要,若没有理解清楚,便难以理解为什么会wa。
下面的数据就是一个trick (对于我的代码,即 dfs 时没有判断长度的
1
4
ACGT
CCC
CGGTTTTTC
TACG

图论

loj 1108 - Instant View of Big Bang

在有向图中,求出可以到达负环的那些点。
从负环反向遍历即可。
关键是检测出所有负环,并且把上面的点标记出来。
spfa和bellman-ford都可以,我们只要标记在第n+1轮还能被松弛的点就好。(因为这些点或在负环上,或可以有负环到达
但不解的是,最开始yy的dfs找负环竟然WA了 - -

搜索

loj 1127 - Funny Knapsack

meet-in-the-middle
贴个非DFS的

int n, W;int as[35];typedef pair<LL, int> P;void calc(vector<P>& v) {    for(int i=v.size()-2; i>=0; --i)        v[i].second += v[i+1].second;}void calc(map<LL, int>& xm, int s, int t) {    map<LL, int>::reverse_iterator it;    xm[0] = 1;    stack<P> tmp;    for(int i=s;i<t;++i) {        for(it=xm.rbegin(); it!=xm.rend(); ++it)            if ( it->first + as[i] <= W )                tmp.push( make_pair(it->first + as[i], it->second) );        while ( !tmp.empty() ) {            xm[tmp.top().first] += tmp.top().second;            tmp.pop();        }    }}int sol() {    int k = n/2;    map<LL, int> xm, ym;    calc(xm, 0, k); calc(ym, k, n);    vector<P> v1, v2;    map<LL, int>::reverse_iterator it;    map<LL, int> & ma = xm;    map<LL, int> & mb = ym;    for(it = ma.rbegin(); it != ma.rend(); ++ it) v1.push_back( *it );    for(it = mb.rbegin(); it != mb.rend(); ++ it) v2.push_back( *it );    calc(v2);    int ret = 0;    for(int i=0;i<v1.size();++i) {        P res = make_pair(W - v1[i].first, INT_MAX);        int pos = lower_bound(v2.begin(), v2.end(), res, greater<P>() ) - v2.begin();        if ( pos >= v2.size() ) continue;        ret += v1[i].second * v2[pos].second;    }    return ret;}int main() {#ifndef ONLINE_JUDGE    freopen("input.in", "r", stdin);#endif    int t, cas = 0; scanf("%d", &t);    while ( t -- ) {        scanf("%d%d", &n, &W);        rep(i, 0, n-1) scanf("%d", as+i);        printf("Case %d: %d\n", ++cas, sol());    }    return 0;}

数学类

loj 1132 - Summing up Powers

1) 类似二分法求等比数列, 二分同时保存 (length,power)这样的状态。
2) 构造矩阵递推
根据
Ckkik+Ck1kik1+...+C0ki0=(i+1)k
来构造出矩阵
http://www.cnblogs.com/jianglangcaijin/p/3443842.html

0 0