一些题目小结6.29

来源:互联网 发布:东方快车杀人事件知乎 编辑:程序博客网 时间:2024/04/30 09:12

1.2588: Spoj 10628. Count on a tree
树上不修改第k大。
迷之RE的原因是被精妙地炸掉了intQAQ
然后又PE
然后才A
我想知道bzoj的人是不是蛇精病。。。

#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include <algorithm>#define Rep(i,n) for(int i = 1;i <= n;i ++)#define RepG(i,x) for(int i = head[x];~ i;i = edge[i].next)#define v edge[i].to#define u t[x]#define o t[y]#define e t[z]#define s t[p]#define mid ((long long)l + r >> 1)#define lson u.lc,l,mid,o.lc#define rson u.rc,mid + 1,r,o.rcusing namespace std;const int N = 100005;const int inf = (1ll << 31) - 5;struct Tree{int lc,rc,cnt;}t[N * 40];struct Edge{int next,to;}edge[N << 1];int top[N],rt[N],dep[N],fa[N],sz[N],n,m,a[N],cnt,head[N],val,son[N],tot;void save(int a,int b){edge[cnt] = (Edge){head[a],b},head[a] = cnt ++;}void dfs(int x){sz[x] = 1;RepG(i,x)if(v != fa[x]){fa[v] = x,dep[v] = dep[x] + 1,dfs(v),sz[x] += sz[v];if(sz[v] > sz[son[x]])son[x] = v;}}void dfs(int x,int tp){top[x] = tp;if(son[x])dfs(son[x],tp);RepG(i,x)if(v != fa[x] && v != son[x])dfs(v,v);}void Ins(int &x,int l,int r,int y){x = ++ tot;u = o;u.cnt ++;if(l == r)return;val <= mid ? Ins(lson) : Ins(rson);}void ReBuild(int x){val = a[x];Ins(rt[x],0,inf,rt[fa[x]]);RepG(i,x)if(v != fa[x])ReBuild(v);}int lca(int x,int y){    while(top[x] != top[y])    {        if(dep[top[x]] < dep[top[y]])swap(x,y);        x = fa[top[x]];    }    return dep[x] < dep[y] ? x : y;}int Qry(int x,int l,int r,int y,int z,int p,int k){    if(l == r)return l;    int res = t[u.lc].cnt + t[o.lc].cnt - t[e.lc].cnt - t[s.lc].cnt;    if(res >= k)return Qry(lson,e.lc,s.lc,k);    else return Qry(rson,e.rc,s.rc,k - res);}int main (){    memset(head,-1,sizeof(head));    scanf("%d%d",&n,&m);    Rep(i,n)scanf("%d",&a[i]);    Rep(i,n - 1){int x,y;scanf("%d%d",&x,&y);save(x,y),save(y,x);}    int ls = 0;    dfs(1),dfs(1,1);    ReBuild(1);    Rep(i,m)    {        int x,y,k;        scanf("%d%d%d",&x,&y,&k);        x ^= ls;        int z = lca(x,y),p = fa[z];        printf("%d",ls = Qry(rt[x],0,inf,rt[y],rt[z],rt[p],k));        if (i != m) puts ("");    }    return 0;}

2.2326: [HNOI2011]数学作业
显然的递推式是:
f[i]=f[i1]10kmodM+imodM
然后我上节课学习了矩阵乘法,刚好来应用一下:

Fnn1=10k00110111Fn1n11

哦然后昨天fsf跟我说:你先发出去我看看排版。
然后我就忘了继续写了QAQ
还被琦爷D了QAQ
代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#define Rep(i,n) for(int i = 1;i <= n;i ++)using namespace std;long long n;int M;struct Matrix{long long a[5][5];};Matrix Init(){Matrix k;memset(k.a,0,sizeof(k.a));return k;}Matrix operator*(Matrix x,Matrix y){    Matrix c = Init();    Rep(i,3)Rep(k,3)Rep(j,3)c.a[i][j] = (c.a[i][j] + ((x.a[i][k] % M) * (y.a[k][j] % M)) % M) % M;    return c;}void print(Matrix c){    Rep(i,3){Rep(j,3)printf("%lld ",c.a[i][j]);puts("");}}Matrix FP(Matrix w,long long p){    //print(w);    //printf("%lld\n",p);    Matrix c = Init();    Rep(i,3)c.a[i][i] = 1;    while(p)    {        if(p & 1)c = c * w;        p >>= 1;        w = w * w;    }    return c;}int main (){    scanf("%lld%d",&n,&M);    Matrix c,ans;    c = Init(),ans = Init();    c.a[1][2] = 1,c.a[1][3] = 1,c.a[2][2] = 1,c.a[2][3] = 1,c.a[3][3] = 1;    ans.a[3][1] = 1;    for(long long i = 1,k = 1;i <= n;i *= 10,k ++)    {        long long j = min(i * 10 - 1,n);        c.a[1][1] = (long long)pow(10,k);c.a[1][2] = c.a[1][3] = c.a[2][3] = c.a[2][2] = c.a[3][3] = 1;        c = FP(c,j - i + 1);        ans = c * ans;    }    printf("%lld\n",ans.a[1][1]);    return 0;}

3.虽然是奶牛题然而感觉还是很可做
(至少感觉思路很好)
Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务。于是,FJ必须为此向电信公司支付一定的费用。 FJ的农场周围分布着N(1<=N<=1,000)1..N顺次编号的废弃的电话线杆,任意两根电话线杆间都没有电话线相连。一共P(1<=P<=10,000)对电话线杆间可以拉电话线,其余的那些由于隔得太远而无法被连接。 第i对电话线杆的两个端点分别为AiBi,它们间的距离为 Li(1<=Li<=1,000,000)。数据中保证每对AiBi最多只出现1次。编号为1的电话线杆已经接入了全国的电话网络,整个农场的电话线全都连到了编号为N的电话线杆上。也就是说,FJ的任务仅仅是找一条将1号和N号电话线杆连起来的路径,其余的电话线杆并不一定要连入电话网络。 经过谈判,电信公司最终同意免费为FJ连结K(0<=K<N)对由FJ指定的电话线杆。对于此外的那些电话线,FJ需要为它们付的费用,等于其中最长的电话线的长度(每根电话线仅连结一对电话线杆)。如果需要连结的电话线杆不超过 K对,那么FJ的总支出为0。 请你计算一下,FJ最少需要在电话线上花多少钱。
题解:思路很明确是二分答案,然后问题是之后怎么办。
之后显然是把>W的那些边都变成1,其余变为0跑一下最短路就成了。
这个题的思路其实很像HeoiD1T2我会说。。。?

#include <cstdio>#include <cstring>#include <algorithm>#define Rep(i,n) for(int i = 1;i <= n;i ++)#define v edge[i].to#define RepG(i,x) for(int i = head[x];~ i;i = edge[i].next)using namespace std;const int N = 1005;struct Edge{int next,to,w;}edge[N * 20];int n,m,K,dis[N],head[N],q[N * 40],cnt;bool vis[N];void save(int a,int b,int c){edge[cnt] = (Edge){head[a],b,c},head[a] = cnt ++;}bool spfa(int ans){    memset(dis,127,sizeof(dis));    int h,t;    dis[1] = 0;h = 0,t = 1,q[0] = 1;vis[1] = 1;    while(h != t)    {        int x = q[h ++];        if(h == 1024)h = 0 ;        RepG(i,x)            if(dis[v] > dis[x] + (bool)(edge[i].w > ans))            {                dis[v] = dis[x] + (bool)(edge[i].w > ans);                if(!vis[v])q[t ++] = v,vis[v] = 1;                if(t == 1024)t = 0;            }        vis[x] = 0;    }    return dis[n] <= K;}int main (){    memset(head,-1,sizeof(head));    scanf("%d%d%d",&n,&m,&K);       Rep(i,m)    {        int a,b,c;        scanf("%d%d%d",&a,&b,&c);        save(a,b,c),save(b,a,c);    }    int l = 0,r = 1000001,ans = -1;    while(l <= r)    {        int mid = l + r >> 1;        if(spfa(mid))ans = mid,r = mid - 1;        else l = mid + 1;    }    printf("%d",ans);    return 0;}

4.每年万圣节,威斯康星的奶牛们都要打扮一番,出门在农场的N(1≤N≤100000)个牛棚里转悠,来采集糖果.她们每走到一个未曾经过的牛棚,就会采集这个棚里的1颗糖果. 农场不大,所以约翰要想尽法子让奶牛们得到快乐.他给每一个牛棚设置了一个“后继牛棚”.牛棚i的后继牛棚是Xi.他告诉奶牛们,她们到了一个牛棚之后,只要再往后继牛棚走去,就可以搜集到很多糖果.事实上这是一种有点欺骗意味的手段,来节约他的糖果. 第i只奶牛从牛棚i开始她的旅程.请你计算,每一只奶牛可以采集到多少糖果.
窝看到第一眼的时候:
SB题,一眼秒。
然后就WA了。。。
然而大体思路是对的只不过自己智障写挂了QAQ
首先缩点并且重建整个图,考虑到在一个scc上的点可以获得它的所有后继的答案,那么我们记忆化搜索一发即可。
然后就没有了QAQ

#include <cstdio>#include <cstring>#include <algorithm>#define Rep(i,n) for(int i = 1;i <= n;i ++)#define RepG(i,x) for(int i = head[x];~ i;i = edge[i].next)using namespace std;const int N = 100005;int to[N],n,cnt,head[N],dfn[N],stk[N],tp,low[N],dsz,scc,bel[N],sz[N];bool vis[N],del[N];struct Edge{int next,to;}edge[N];void save(int a,int b){edge[cnt] = (Edge){head[a],b},head[a] = cnt ++;}void dfs(int x){    dfn[stk[++ tp] = x] = low[x] = ++ dsz;int y;    int v = to[x];    if(!dfn[v])dfs(v),low[x] = min(low[v],low[x]);    else if(!del[v])low[x] = min(dfn[v],low[x]);    if(dfn[x] == low[x]){++ scc;do{bel[y = stk[tp --]] = scc,sz[scc] ++;del[y] = 1;}while(y != x);}}#define v edge[i].toint ans[N];void ReBuild(){Rep(i,n)if(bel[i] != bel[to[i]])save(bel[i],bel[to[i]]);}int ReDfs(int x){    if(ans[x])return ans[x];    ans[x] = sz[x];    RepG(i,x)ans[x] += ReDfs(v);    return ans[x];}int main (){    memset(head,-1,sizeof(head));    scanf("%d",&n);    Rep(i,n)scanf("%d",&to[i]);    Rep(i,n)if(!dfn[i])dfs(i);    ReBuild();    Rep(i,n)printf("%d\n",ReDfs(bel[i]));    return 0;}

剩下A的几道题都是窝东拼西凑凑出的水题QAQ
哦其实我上面几道题也是水题QAQ
真是颓废的一天QAQ

0 0
原创粉丝点击