[雅礼NOIP2018集训 day3]

考试的时候刚了T1两个小时线段树写了三个子任务结果发现看错了题目,于是接下来一个半小时我自闭了

result=历史新低

这告诉我们,打暴力要端正态度,尤其是在发现自己之前出锅的情况下要保持心态的平和,不能和今天的比赛一样后面差不多直接弃疗


T1:

题意就是我们要做多次倒三角的区间加,最后统计全部的异或和。不幸的是当我看到空间限制512MB的时候就直接暴力上线段树了,凉心出题人

正解是很巧妙的二维前缀和做法

考虑我们暴力怎么做--对倒三角的每一行差分,最后统计一次,这样的复杂度是$O(nq)$的

这个时候可以发现每一次倒三角我们改变的差分序列是可以二维差分优化的。其实就是对三角的竖着的直角边和那条斜边在维护差分数组,最后再统计答案就好了

其他的做法不会啊,果然还是太弱

#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<time.h>
using namespace std;
typedef long long ll;

const int N=3e3+15; 
ll n,q;
ll a[N][N],b[N][N],c[N][N],d[N][N],e[N][N];
inline ll read()
{
    char ch=getchar();
    ll s=0,f=1;
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
    return s*f;
}
int main()
{
    freopen("u.in","r",stdin);
    freopen("u.out","w",stdout);
    //double st=clock();
    n=read();q=read();
    while (q--)
    {
        ll r=read(),c=read(),l=read(),s=read();
        a[r][c]+=s;a[r+l][c]-=s;
        b[r-c+n-1][r]-=s;b[r-c+n-1][r+l]+=s;
    }
    for (int i=1;i<=n;i++)    
        for (int j=1;j<=n;j++)
        {    
            c[i][j]=c[i-1][j]+a[i][j];
            d[i][j]=d[i-1][j-1]+b[i-j+n][i];
            e[i][j]=e[i][j-1]+c[i][j]+d[i][j]; 
        }
    /*for (int i=1;i<=n;i++)    
    {
        for (int j=1;j<=n;j++) 
            printf("%d ",c[i][j]+d[i][j]);
        printf("\n");
    }*/
    //printf("\n");
    ll ans=0;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++) ans^=e[i][j];
    /*for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++) printf("%d ",e[i][j]);
        printf("\n");
    }*/
    printf("%lld\n",ans);
    //double ed=clock();
    //printf("%lf\n",ed-st); 
}
View Code

T2:

数据范围好像就是给你状压DP的,状态分别是当前还剩下的球(一个0/1序列)和剩下球的个数(这里有个坑点,不能直接通过0/1序列记忆化,因为最高位可能是0,这样可能出现长度不同但是0/1序列相同的两个状态)

我们数组记忆化肯定是不行的,那么大的就只好开map了。鉴于上述的坑点,看代码注释了解如何避免吧

所谓最优策略,其实就是状态转移的时候取max就好

还有就是关于那个erase函数,删掉一个球,相当于在一个二进制数里面去掉一位。设去掉的二进制位为k,笔者的思路就是把0-k-1先取出来(预处理111...这样的数字&一下就好了),再把原来的数后面变成0(注意0的个数要比原来的位数少1,因为有一位被去掉了)

然后这题好像就A了,考场上像个傻叉一样的写搜索,关键是之前的1分暴力写完了没打return 0,输出两个答案的我彻底凉凉了,22分暴力都没有拿到

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<map>
using namespace std;

const int N=31;
int n,k;
int pre[N];
namespace calc
{    
    const int M=24;
    double a[1<<M+1];
    map <int,double> p[N];
    void init()
    {
        for (int i=0;i<1<<M+1;i++) a[i]=-1;
    }
    bool count(int bit,int len)
    {
        if (len<=M) return a[1<<len|bit]!=-1;//坑点处理在这儿,看到那个|没有?std太伟大了 
        else return p[len].count(bit);
    }
    double &find(int bit,int len)
    {
        if (len<=M) return a[1<<len|bit];
        else return p[len][bit];
    }
}
int erase(int bit,int i)
{
    return (bit&pre[i-1])|((bit>>(i+1))<<i);
}
double dfs(int bit,int len)
{
    if (len<=k) return 0;
    if (calc::count(bit,len)) return calc::find(bit,len);//记忆化 
    double &res=calc::find(bit,len);
    res=0;
    for (int i=0,j=len-1;i<=j;++i,--j)
    {
        if (i<j) res+=max(dfs(erase(bit,i),len-1)+(bit>>i&1),dfs(erase(bit,j),len-1)+(bit>>j&1))*2;//*2是因为正的第i个,反的第len-i+1个也是这个位置 
        else res+=dfs(erase(bit,i),len-1)+(bit>>i&1);
    }
    return res/=len;//别忘了/len 
}
int main()
{
    //freopen("v.in","r",stdin);
    //freopen("v.ans","w",stdout);
    scanf("%d%d",&n,&k);
    char ch[N];
    scanf("%s",ch);
    calc::init();
    pre[0]=1;
    for (int i=1;i<N;i++) pre[i]=pre[i-1]|(1<<i);
    int bit=0;
    k=n-k;
    for (int i=0;i<n;i++)
    {
        bit|=(ch[i]=='W')<<i;
    }
    printf("%.10lf\n",dfs(bit,n));
    return 0;
} 
View Code

T3:

有两个需要明确的性质

1.不要变的边我们不变,因为变了我们还要至少花费一次代价把它变回来

2.一棵树里变了的边的条数就是在这些边覆盖的点集中奇数度数点的个数/2(度数是翻转的边带来的)。这个好像挺显然的,因为一条翻转的边只会给两个端点带来奇数的度数,中间的都是偶数的度数

考虑dp,dp[x][0/1]表示节点x与父亲的边是否翻转,最少的奇数点的个数和翻转的总长度(我们的dp数组存的这样的结构体)

发现目标是在最少的奇数点的基础上最小化翻转的总长度,也就是前者优先,于是我们用pair

考虑如何转移

设x与父亲的边的类型是type(if (d==2) type=2 else type=c^d)

如果type==1||type==2的话,dp[x][0]显然可以设成inf了,我们只能转移dp[x][1]。设tmp0表示仅仅考虑x的子树,当前点x不是路径端点的最小代价(注意x可能是被一条路径经过);tmp1表示仅仅考虑x的子树,当前点是路径端点的最小代价。这两个如何计算参见代码。dp[x][1]=max((tmp0.fi+1,tmp0.se+1),(tmp1.fi,tmp1.se+1)) 

还有就是type==0||type==2,这种情况也差不多,不理解参考代码吧

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#define pii pair<int,int>
using namespace std;

const int N=1e5+15;
const int inf=1e9+7;
int n;
vector <pii> mp[N];
pii dp[N][2];
inline int read()
{
    char ch=getchar();
    int s=0,f=1;
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
    return s*f;
}
pii operator + (pii a,pii b){return make_pair(a.first+b.first,a.second+b.second);}
void dfs(int x,int fa,int type)
{
    pii tmp0(0,0),tmp1(inf,inf);//tmp0是不以它为断电答案,tmp1是以它为端点的最小答案
    for (int i=0;i<mp[x].size();i++) 
    {
        int y=mp[x][i].first;
        if (y==fa) continue;
        dfs(y,x,mp[x][i].second);
        pii nxt0,nxt1;
        nxt0=min(tmp0+dp[y][0],tmp1+dp[y][1]);
        nxt1=min(tmp0+dp[y][1],tmp1+dp[y][0]);
        tmp0=nxt0;tmp1=nxt1;
    }
    if (type==2||type==0)
    {
        dp[x][0]=min(tmp0,make_pair(tmp1.first+1,tmp1.second));
    }
    else dp[x][0]=make_pair(inf,inf);
    if (type==2||type==1)
    {
        dp[x][1]=min(make_pair(tmp1.first,tmp1.second+1),make_pair(tmp0.first+1,tmp0.second+1));
    }
    else dp[x][1]=make_pair(inf,inf);
}
int main()
{
    n=read();
    for (int i=1;i<n;i++)
    {
        int a=read(),b=read(),c=read(),d=read();
        if (d!=2) d=c^d;
        mp[a].push_back(make_pair(b,d));
        mp[b].push_back(make_pair(a,d));
    }
    dfs(1,-1,0);
    printf("%d %d\n",dp[1][0].first/2,dp[1][0].second);
    return 0;
}
View Code

转载于:https://www.cnblogs.com/xxzh/p/9740452.html

数据中心机房是现代信息技术的核心设施,它承载着企业的重要数据和服务,因此,其基础设计与规划至关重要。在制定这样的方案时,需要考虑的因素繁多,包括但不限于以下几点: 1. **容量规划**:必须根据业务需求预测未来几年的数据处理和存储需求,合理规划机房的规模和设备容量。这涉及到服务器的数量、存储设备的容量以及网络带宽的需求等。 2. **电力供应**:数据中心是能源消耗大户,因此电力供应设计是关键。要考虑不间断电源(UPS)、备用发电机的容量,以及高效节能的电力分配系统,确保电力的稳定供应并降低能耗。 3. **冷却系统**:由于设备密集运行,散热问题不容忽视。合理的空调布局和冷却系统设计可以有效控制机房温度,避免设备过热引发故障。 4. **物理安全**:包括防火、防盗、防震、防潮等措施。需要设计防火分区、安装烟雾探测和自动灭火系统,设置访问控制系统,确保只有授权人员能进入。 5. **网络架构**:规划高速、稳定、冗余的网络架构,考虑使用光纤、以太网等技术,构建层次化网络,保证数据传输的高效性和安全性。 6. **运维管理**:设计易于管理和维护的IT基础设施,例如模块化设计便于扩展,集中监控系统可以实时查看设备状态,及时发现并解决问题。 7. **绿色数据中心**:随着环保意识的提升,绿色数据中心成为趋势。采用节能设备,利用自然冷源,以及优化能源管理策略,实现低能耗和低碳排放。 8. **灾难恢复**:考虑备份和恢复策略,建立异地灾备中心,确保在主数据中心发生故障时,业务能够快速恢复。 9. **法规遵从**:需遵循国家和地区的相关法律法规,如信息安全、数据保护和环境保护等,确保数据中心的合法运营。 10. **扩展性**:设计时应考虑到未来的业务发展和技术进步,保证机房有充足的扩展空间和升级能力。 技术创新在数据中心机房基础设计及规划方案中扮演了重要角色。例如,采用虚拟化技术可以提高硬件资源利用率,软件定义网络(SDN)提供更灵活的网络管理,人工智能和机器学习则有助于优化能源管理和故障预测。 总结来说,一个完整且高效的数据中心机房设计及规划方案,不仅需要满足当前的技术需求和业务目标,还需要具备前瞻性和可持续性,以适应快速变化的IT环境和未来可能的技术革新。同时,也要注重经济效益,平衡投资成本与长期运营成本,实现数据中心的高效、安全和绿色运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值