您的位置:首页 > 其它

[swust]Fighting for 2017 season contest 8 快速幂,简单DP,暴力or指针交换,树上背包,线段树区间开根

2017-03-12 16:33 591 查看
题目地址:https://oj.splayx.com/vjudge/contest/view.action?cid=4#problem/A

A:水题,一个快速幂搞定。

//tvoj 1116

#include <bits/stdc++.h>
using namespace std;
const int mod = 7;
int powmod(int a, int b){
int res = 1;
while(b){
if(b&1) res = res*a%mod;
a = a*a%mod;
b>>=1;
}
return res;
}
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
int ans = 0;
for(int i = 1; i <= n; i++){
int x = powmod(2, i);
int y = ((i%7)*(i%7))%7;
if((x-y+7)%7==0) ans++;
}
printf("%d\n", ans);
}
return 0;
}


B:显然应该是一个DP。状态表示为 dp[i][0]表示第i天,我们能换得最多的马克,dp[i][1]表示第i天,我们能换得最多的美元。然后转移就非常简单了。

dp[i][0] = max(dp[i-1][0], dp[i-1][1]*(double)a[i]/100.0);
dp[i][1] = max(dp[i-1][1], dp[i-1][0]/(double)(a[i])*100.0);


就是美元和马克的相互变换,计算对应的答案。

//tyvj 1095

#include <bits/stdc++.h>
using namespace std;
int n, a[105];
double dp[105][2]; //dp[i][0]表示第i天,我们能换得最多的马克,dp[i][1]表示第i天,我们能换得最多的美元

int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
dp[1][0] = a[1];
dp[1][1] = 100;
for(int i = 2; i <= n; i++){
dp[i][0] = max(dp[i-1][0], dp[i-1][1]*(double)a[i]/100.0);
dp[i][1] = max(dp[i-1][1], dp[i-1][0]/(double)(a[i])*100.0);
}
printf("%.2f\n", dp
[1]);
}


C:行列的交换可以用指示行列的指针来间接交换,或者由于数据水直接暴力也可过。

//tyvj 2012

#include <bits/stdc++.h>
using namespace std;
int a[710][710], row[710], col[710];
int main()
{
int n, k;
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
scanf("%d", &a[i][j]);
}
}
for(int i = 1; i <= n; i++) row[i] = i, col[i] = i;
while(k--){
char op[10];
int x, y;
scanf("%s%d%d", op, &x, &y);
if(op[0] == 'R'){
swap(row[x], row[y]);
}
else if(op[0] == 'C'){
swap(col[x], col[y]);
}
else{
printf("%d\n", a[row[x]][col[y]]);
}
}
}


D,相当于树上的分组背包问题。只不过这里没有组里只能取一个的限制,而是可以取多个。我们考虑dp[i][j]表示第i门课程,包括其自身在内选j门子课程的最大收益。那么对于节点i转移比较简单应该是dp[i][j]=max(dp[i][j], dp[i][j-k]+dp[(i的子结点v)][k] k∈[0,j) (不能取k=j,因为至少有一门是先修课v) j倒序循环(分组背包思想)

//tyvj 1051

#include <bits/stdc++.h>
using namespace std;
const int maxn = 410*410;
int n, m, edgecnt, head[410];
int dp[410][410], score[410];
struct edge{
int v, nxt;
edge(){}
edge(int v, int nxt):v(v), nxt(nxt){}
}E[maxn];
void init(){
edgecnt = 0; memset(head, -1, sizeof(head));
}
void addedge(int u, int v){
E[edgecnt].v = u, E[edgecnt].nxt = head[v], head[v] = edgecnt++;
}
void dfs(int x){
dp[x][1] = score[x];
for(int i = 2; i <= m; i++) dp[x][i] = 0;
for(int i = head[x]; ~i; i = E[i].nxt){
int v = E[i].v;
dfs(v);
for(int j = m; j; j--){
for(int k = 0; k < j; k++){
dp[x][j] = max(dp[x][j], dp[x][j-k]+dp[v][k]);
}
}
}
}
int main(){
init();
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++){
int u;
scanf("%d%d", &u, &score[i]);
addedge(i, u);
}
m++;
dfs(0);
printf("%d\n", dp[0][m]);
return 0;
}


E,线段树区间开根,考虑一个1e12的数,不超过10次可以开到1,所以我们打个lazy标记就可以很快把一个线段缩成一个点,线段树经典套路了。注意l有可能小于r。

//tyvj 1941
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
#define lson l,m,o*2
#define rson m+1,r,o*2+1
namespace segementtree{
int c[maxn*4];
long long sum[maxn*4];
void pushup(int o){
sum[o] = sum[o*2]+sum[o*2+1];
c[o] = c[o*2] || c[o*2+1] ? 1 : 0;
}
void build(int l, int r, int o)
{
if(l == r){
scanf("%lld", &sum[o]);
c[o] = sum[o]>1?1:0;
return;
}
int m = (l+r)/2;
build(lson);
build(rson);
pushup(o);
}
void update(int L, int R, int l, int r, int o){
if(!c[o]) return;
if(l == r){
sum[o] = sqrt(sum[o]);
if(sum[o]<=1) c[o]=0;
return;
}
int m=(l+r)/2;
if(L<=m&&c[o*2]) update(L, R, lson);
if(m<R&&c[o*2+1]) update(L, R, rson);
pushup(o);
}
long long query(int L,int R, int l, int r, int o){
if(L<=l&&r<=R) return sum[o];
int m=(l+r)/2;
if(R<=m) return query(L, R, lson);
else if(L>m) return query(L,R, rson);
else{
return query(L,m,lson)+query(m+1,R,rson);
}
}
}
using namespace segementtree;
int main()
{
int n, m;
scanf("%d", &n);
build(1, n, 1);
scanf("%d", &m);
for(int i = 1; i <= m; i++){
int cmd, l, r;
scanf("%d%d%d", &cmd, &l, &r);
if(l>r) swap(l, r);
if(cmd == 1) printf("%lld\n", query(l, r, 1, n, 1));
else update(l, r, 1, n, 1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐