2016长乐夏令营Day2

来源:互联网 发布:淘宝联盟电脑版和手机 编辑:程序博客网 时间:2024/04/29 22:34

T1:

反正要用sliding windows~,至于数字的处理

一开始用离散化,但是长乐的老爷机死都不让我过nlogn

最后Hash一发总算A了

#include<cstdio>#include<cstdlib>#include<algorithm>#include<iostream>#include<vector>#include<queue>#include<cstring>#include<stack>#include<cmath>using namespace std;const int maxn = 1E6 + 10;const int Hash = 67;const int mo = 15000131;int n,ans = 0,a[maxn],b[maxn],c[15000132];int Lower_Bound(int l,int r,int x){if (l == r) return l;int mid = (l+r) >> 1;if (x <= a[mid]) return Lower_Bound(1,mid,x);else return Lower_Bound(mid+1,r,x);}int main(){#ifdef DMC   freopen("DMC.txt","r",stdin);#else   freopen("snow.in","r",stdin);   freopen("snow.out","w",stdout);#endif/*for (int i = 2; i < maxn*15; i++)if (!pri[i]) for (int j = i*2; j < maxn*15; j += i)pri[j] = 1;for (int i = maxn*15-1; i; i--)if (!pri[i]) {cout << i; return 0;}*/cin >> n;for (int i = 1; i <= n; i++) {scanf("%d",&a[i]);for (int j = 1; j <= 3; j++) {a[i] %= mo;a[i] *= Hash;}a[i] %= mo;}int i = 1;for (int j = 1; j <= n; j++) {if (!c[a[j]]) ++c[a[j]];else for (;;) {--c[a[i]]; ++i;if (!c[a[j]]) {++c[a[j]]; break;}}ans = max(ans,j-i+1);}cout << ans;return 0;}


T2:

找个置换的规律,画画图就好了

#include<cstdio>#include<cstdlib>#include<algorithm>#include<iostream>#include<vector>#include<queue>#include<cstring>#include<stack>#include<cmath>using namespace std;const int maxn = 110;int n,ans,a[maxn];void Work(){for (;;) {if (a[1] == 1) return;swap(a[1],a[a[1]]);++ans;}}bool Judge(){for (int i = 1; i <= n; i++)if (a[i] != i)return 0;return 1;}int main(){#ifdef DMC   freopen("DMC.txt","r",stdin);#else   freopen("net.in","r",stdin);   freopen("net.out","w",stdout);#endifcin >> n;for (int i = 1; i <= n; i++) scanf("%d",&a[i]);for (;;) {if (Judge()) {cout << ans; return 0;}if (a[1] == 1) for (int j = 2; j <= n; j++)if (a[j] != j) {swap(a[1],a[j]);++ans; break;}Work();}return 0;}


T3:

加个虚拟节点,枚举不要的宠物,每次做一遍最小生成树

#include<cstdio>#include<cstdlib>#include<algorithm>#include<iostream>#include<vector>#include<queue>#include<cstring>#include<stack>#include<cmath>using namespace std;const int maxn = 3E5 + 10;struct E{int a,b,w;bool operator < (const E &B) const {return w < B.w;}}edgs[maxn],e[maxn];int n,m,now,ans = ~0U>>1,tot,cnt,fa[300];int fat(int x){return x == fa[x]?x:fa[x] = fat(fa[x]);}int main(){#ifdef DMC   freopen("DMC.txt","r",stdin);#else   freopen("lovelygf.in","r",stdin);   freopen("lovelygf.out","w",stdout);#endifcin >> n;for (int i = 1; i <= n; i++) {int z; scanf("%d",&z);edgs[++tot] = (E){0,i,z};}cin >> m;for (int i = 1; i <= m; i++) {int x,y,z; scanf("%d%d%d",&x,&y,&z);edgs[++tot] = (E){x,y,z};}for (int i = 1; i <= n; i++) {int sum; sum = now = cnt = 0;for (int j = 0; j <= n; j++) fa[j] = j;for (int j = 1; j <= tot; j++)if (edgs[j].a != i && edgs[j].b != i)e[++cnt] = edgs[j];sort(e + 1,e + cnt + 1);for (int j = 1; j <= cnt; j++) {int FA = fat(e[j].a);int FB = fat(e[j].b);if (FA != FB) {++sum;now += e[j].w;fa[FA] = FB;}if (sum == n - 1) break;}if (sum == n - 1) ans = min(ans,now);}cout << ans;return 0;}

嗯。。虽然算出了e数组,但是写的时候写成edgs,作死


T4:

dp。。。多亏认识帅副

把原图看成RT三角形

每个点至少要学习其右上角的点和这个点往上所有点

f[i][j][k]:学习第i行第j列的技能,一共学了k个,最大威力

f[i][j][k] = max{f[x][j+1][l] + sum[i][j]}  (k = i+l,i-1<=x<=m)

最后,f[x][j+1][j]可以从下往上推的时候保留最大值

#include<cstdio>#include<cstdlib>#include<algorithm>#include<iostream>#include<vector>#include<queue>#include<cstring>#include<stack>#include<cmath>using namespace std;const int maxn = 60;typedef long long LL;int n,m,tot,sa[60][60],sb[60][60];LL a[60][60],f[51][51][501],ma[51][51][501],sum[51][51];LL getLL(){LL ret = 0;char ch = getchar();while (ch < '0' || '9' < ch) ch = getchar();while ('0' <= ch && ch <= '9')ret = ret*10LL + 1LL*(ch-'0'),ch = getchar();return ret;}int main(){#ifdef DMC   freopen("DMC.txt","r",stdin);#else   freopen("skill.in","r",stdin);   freopen("skill.out","w",stdout);#endifcin >> n >> m;for (int i = 1; i <= n; i++) for (int j = n-i+1; j; j--) sa[i][j] = sa[i-1][j+1] + i;for (int i = 1; i <= n; i++)for (int j = 1; j <= n-i+1; j++)a[i][j] = getLL(),sum[i][j] = a[i][j] + sum[i-1][j];for (int i = n; i; i--) {for (int j = n-i+1; j > 0; j--) {for (int l = sa[j-1][i+1]; l <= m; l++)if (j + l <= m)f[j][i][j+l] = sum[j][i] + ma[j-1][i+1][l];else break;for (int l = sa[j][i]; l <= m; l++)ma[j][i][l] = max(f[j][i][l],ma[j+1][i][l]);}for (int l = 0; l <= m; l++) {f[0][i][l] = ma[0][i+1][l];ma[0][i][l] = max(f[0][i][l],ma[1][i][l]);}}LL ans = 0;for (int i = 1; i <= n; i++)for (int j = 1; j <= n-i+1; j++)ans = max(ans,f[i][j][m]);cout << ans;return 0;}

写的时候漏判行数为0的边界。。。GGGG


0 0