摘要:
阅读全文
摘要:
题目大意:已知一个连接了q条路的城镇,求最小生成树。#include #include #include using namespace std;struct data{int l,x,y;}seg[10010];int r,f[10010],n,l,cnt,x,y,fx,fy,now,p,ans;char c;int sf(int x){return f[x]==x?x:f[x]=sf(f[x]);}void scan(int &x){ while(c=getchar(),c'9');x=c-'0'; while(c=getchar(),c>=& 阅读全文
摘要:
//插入void insert(char *s,char *s1){ for(int l=strlen(s),x=0,i=0;i<l;i++){ if(!trie[x].son[s[i]-'a'])trie[x].son[s[i]-'a']=++cnt; x=trie[x].son[s[i]-'a']; if(i==l-1)strcpy(trie[x].hash,s1); }}//查找int find(char *s){ for(int l=strlen(s),x=0,i=0;i<l;i++){ if(!trie[x].... 阅读全文
摘要:
题解:在路边有一行树,给出它们的坐标和高度,先按X坐标排序。记录排名,记为rankx,再按它们的高度排序,记录排名,记为rankh。两颗树i,j的差异度为fabs(rankx[i]-rankx[j])*min(rankh[i],rankh[j])最后求出任异两颗树差异度的和。题解:首先,需要解决的是min(rh)的问题,对于这个问题,只要离散化之后按rh从大到小排序顺序求解即可,然后用树状数组维护之前出现rx比当前值小的个数与总和,那么同时就可以计算rx比当前大的个数和总和了,那么就可以依次计算出答案了。#include #include #include using namespace st 阅读全文
摘要:
题目大意:给定一个序列,求出其所有的上升子序列。题解:一开始我以为是动态规划,后来发现离散后树状数组很好做,首先,c保存的是第i位上升子系列有几个,那么树状数组的sum就直接是现在的答案了,不过更新时不要忘记加1,因为当前元素本身也是一个子序列,比如数列离散后为1 3 2 4 5,那么第一位得到之前的答案为0,更新时1位加1,第二位算出为1,更新时3位加(1+1),第三位也一样,一次类推,同树状数组求逆序对的方法一样,但是更新的不是1,而是之前所有的答案数加1。#include #include using namespace std; const int N=100005;... 阅读全文
摘要:
题目大意:给定n个数的序列,让我们找前面k个区间的最大值之和,每个区间长度为n/k,如果有剩余的区间长度不足n/k则无视之。现在让我们找最小的k使得和严格大于m。题解:二分k,然后求RMQ检验。ST算法:#include #include #include using namespace std; const int maxn=200010; int d[maxn][30]; int a[maxn]; void init_rmq(int n){ for(int i=0;im)return true; } return false; } int... 阅读全文
摘要:
//初始化void init_rmq(int n){ for(int i=0;i<n;i++)d[i][0]=a[i]; for(int j=1;(1<<j)<=n;j++){ for(int i=0;i+(1<<j)-1<n;i++) d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]); } } //查询int query_rmq(int L,int R){ int k=0; while(1<<(k+1)<=R-L+1)k++; return max(d[... 阅读全文
摘要:
题解:求树上最短路,所以直接LCA:倍增求LCA:#include int f[10010][18];int s[10010],d[10010],from[10010];int g[10010],nxt[20010],edv[20010],edw[20010],cnt;bool vis[10010];int q,a,b,e,n,m,i,j,x,y,tmp;void swap(int &a,int &b){int c=a;a=b;b=c;}void add(int u,int v,int w){ edv[++cnt]=v;edw[cnt]=w; nxt[cnt]=g[u];g[u 阅读全文
摘要:
阅读全文
摘要:
题目大意:给定一个体积为N*N*N立方体,每个单位小立方体A[x][y][z]里有一个值,初始值全部为0,我们可以对立方体进行一下两种操作:0表示查询A[x][y][z]的奇偶性1表示对子立方体的每个元素的值进行增减题解:首先显然是三维的树状数组,然后对于区间的修改,可以用前缀和来解决,在起点改变一下,终点的后一位改变一下即可。#include #include #define N 105using namespace std;int c[N][N][N];int n;void add(int x,int y,int z){ int i,j,k; for(i=x;i0;i-=i&-.. 阅读全文
摘要:
权值线段树#include #include const int N=200000,M=220000;int k,q,x,y,sum[M>1; if(t>1,tmp=0; if(L>1,tmp=sum[x'9');x=c-'0'; while(c=getchar(),c>='0'... 阅读全文
摘要:
树状数组#include #include using namespace std;const int N=50010;int T,n,cnt=1,x,y;char s[6];int c[N];void init(){for(int i=0;i0)s+=c[x],x-=x&-x;return s;}int main(){ scanf("%d",&T); while(T--){ init(); scanf("%d",&n); for(int i=1;i #include const int N=60000;int T,n,cnt=1 阅读全文
摘要:
二维树状数组#include #include using namespace std;#define N 1005int c[N][N];int i,j,n,num,p,T,cnt=1;int sum(int x,int y){ int i,j,tmp=0; for(i=x;i>0;i-=(i&-i)) for(j=y;j>0;j-=(j&-j)) tmp+=c[i][j]; return tmp;}void add(int x,int y,int num){ for(int i=x;i'9'||c='0')x=x*10+c- 阅读全文
摘要:
题解:如图,哈夫曼编码,不断选取规模最小的两个连接,如样例AAAAABCD,A规模为5,B规模为1,C规模为1,D规模为1,那么A取0,BCD为10,110,111时编码长度最短,那么就是C与D先合并,如图中1,2节点,变为规模为2的点,然后与B(3)相连,最后和A(4)连接。其实题目不需要建立哈夫... 阅读全文
摘要:
题目大意:给定一些正方体的关系,要求一组符合这些关系的正方体坐标,如果不存在符合条件的正方体坐标,IMPOSSIBLE。(Special Judge)实力还是太弱了,完全不会……#include #include #include #define MAXN 2010#define MAXR 500000#define MAX 999999typedef struct edges{ int v,w,next;}edge;int N, R;edge edge_X[MAXR], edge_Y[MAXR], edge_Z[MAXR];int s_X[MAXN], s_Y[MAXN], s_Z[... 阅读全文
摘要:
题解:利用set的判重功能,直接计算出现的字符串数量,同时记录失败的字符串,如果两者相差1,则有冠军,否则没有:#include #include #include using namespace std;int main(){ int n; while(scanf("%d",&n),n){ getchar(); string a,b; set sum; set fail; for(int i=0;i>a>>b; sum.insert(a); sum.insert(b)... 阅读全文
摘要:
题解:裸的topo,注意判重,由于数据升序所以免排序。#include #include using namespace std;#define N 505int map[N][N],n,m,a,b,in[N],ans[N];void topo(){ int top=0,i; memset(ans,0,sizeof ans); while(true){ for(i=1;i<=n;i++)if(in[i]==0)break; if(i==n+1)return; in[i]=-1; ans[top++]=i; ... 阅读全文
摘要:
map……#include #include #include using namespace std;mapmap1;mapmap2;int main(){ string s,secret,usage,tmp; getline(cin,s); while(s!="@END@"){ int find=s.find(']'); secret=s.substr(0,find+1); usage=s.substr(find+2,s.size()-find-2); map1[usage]=secret; ma... 阅读全文
摘要:
题目大意:士兵要学骑扫帚。每个士兵有一个level,level高的能在同一把扫帚上教level低的怎么骑。一个人最多有一个老师,一个学生。也可以没有。给n个士兵的level值,问最少需要多少扫帚。//字典树#include #include int cnt,n,max;char s[50];struct Node{int son[10];int sum;}trie[500000];void insert(char *s){ for(int l=strlen(s),i=0,x=0;imax)max=trie[x].sum; } }}void del(int x){ ... 阅读全文
摘要:
字典树~#include #include using namespace std;int cnt,n;char s[12];struct Node{int sum; int son[26];}trie[500000];void insert(char *s){ for(int l=strlen(s),x=0,i=0;i<l;i++){ if(!trie[x].son[s[i]-'a'])trie[x].son[s[i]-'a']=++cnt; x=trie[x].son[s[i]-'a']; trie[x].sum++; }}int f. 阅读全文