10.03模拟总结

国庆模拟真愉快,真愉快!这只是个开始,之后我们还有4天连续的国庆模拟呢!而且可能不会像今天这么好改了orz。

来吧,我们来看看这些题。

T1.matrix

这道题考试的时候只想到了60分的暴力维护……就是只开一维差分,另一维直接暴力去修改……,不过这样的复杂度是O(np)的,这个肯定会超时。

然后大致想到了使用二维差分去维护,不过不知道怎么实现。(知道查询是可以用前缀和查询的,但是修改怎么修啊orz)

考试结束后听bin哥一讲就明白了,我们只要在右上和左下+1,左下和右上-1即可,这样的话我们就能保证原数组就是差分数组的前缀和。(只要简单想想就能知道啦)

之后我们再跑一遍,维护一次前缀和。

查询的适合只要用四个矩形互相加减即可,老套路了。

来看一下满分的代码。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')
#define de putchar('#')
#define pr pair<int,int>
#define mp make_pair
#define fi first
#define sc second
using namespace std;
typedef long long ll;
const int M = 100005;
const int N = 2005;
const int INF = 1000000009;

int read()
{
    int ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') op = -1;
        ch = getchar();
    }
    while(ch >='0' && ch <= '9')
    {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
    }
    return ans * op;
}

int n,m,p,q,dx,dy,sx,sy,c[N][N];
ll a[N][N];

void build()
{
    rep(q,1,2)
    {
        rep(i,1,n-1)
        rep(j,1,m) a[i+1][j] += a[i][j];
        rep(i,1,n)
        rep(j,1,m-1) a[i][j+1] += a[i][j];
    }
}

int main()
{
    freopen("matrix.in","r",stdin);
    freopen("matrix.out","w",stdout);
    n = read(),m = read(),p = read(),q = read();
    rep(i,1,p)
    {
        dx = read(),dy = read(),sx = read(),sy = read();
        a[dx][dy]++,a[dx][sy+1]--,a[sx+1][dy]--,a[sx+1][sy+1]++;
    }
    build();
    rep(i,1,q)
    {
        dx = read(),dy = read(),sx = read(),sy = read();
        ll g = a[sx][sy] + a[dx-1][dy-1] - a[sx][dy-1] - a[dx-1][sy];
        printf("%lld\n",g);
    }
    return 0;
}

T2.card

好吧说实话第一眼我以为这是个组合题,还以为这是个与HNOI2008那道组合很相像的一道题。不过那道题要求维护的是相同的,那个其实特别好计算,而这道题是要求维护的是相邻两个数只和不能等于k,这个就很麻烦。

我一开始想能不能用组合的方法解决……好吧显然不行。这玩意咋组合啊……反正我是想不出来。想了一段时间之后我觉得换个思路,用递推的方式来做。我只考虑了k  < m的情况,设f[i]表示第i个数选择了1~k-1范围之内的数的方案数,g[i]表示第i个数选择了k~m范围内的数的方案树。

于是乎我们有如下转移:

f[i] = f[i-1] * (k-2) + g[i-1] * (k-1) (还有取模)

g[i] = (g[i-1] + f[i-1]) * (m-k+1) (取模)

然后我就这么傻不拉几的交了上去,还得了50pts。

其实我考试结束之前10分钟突然发现这玩意可以用矩阵加速……然后我没时间写了。

哦,对于k > m的情况,一开始我听了ssy神犇的讲述……不过后来觉得好像还是自己想好懂一些。

其实完全可以照着k < m去推的,这次令f[i]表示选取1~k-m-1的情况的方案数,g[i]表示选择k-m~m的情况的方案数。于是得到以下方程:

f[i] = (f[i-1]  + g[i-1])* (k-m-1);

g[i] = f[i-1] * (2m-k+1) + g[i-1] * (2m-k)

然后这玩意也可以用矩阵加速!然后就可以A了!

看一下满分代码。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')
#define de putchar('#')
#define pr pair<int,int>
#define mp make_pair
#define fi first
#define sc second
using namespace std;
typedef long long ll;
const int M = 2000005;
const ll mod = 1000000007;

ll read()
{
    ll ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
    if(ch == '-') op = -1;
    ch = getchar();
    }
    while(ch >='0' && ch <= '9')
    {
    ans *= 10;
    ans += ch - '0';
    ch = getchar();
    }
    return ans * op;
}

ll m,n,k,f[M],g[M],ans;


struct matrix
{
    ll h[3][3];
    matrix()
    {
        memset(h,0,sizeof(h));
    }
    friend matrix operator * (const matrix &a,const matrix &b)
    {
        matrix c;
        rep(i,1,2)
        rep(j,1,2)
        rep(k,1,2) c.h[i][j] += (a.h[i][k] * b.h[k][j]) % mod,c.h[i][j] %= mod;
        return c;
    }
}a;

matrix mpow(matrix a,ll b)
{
    matrix p;
    rep(i,1,2) p.h[i][i] = 1;
    while(b)
    {
    if(b & 1) p = p * a;
    a = a * a;
    b >>= 1;
    }
    return p;
}

int main()
{
    //freopen("card.in","r",stdin);
    //freopen("card.out","w",stdout);
    m = read(),n = read(),k = read();
    if(k > m)
    {
    a.h[1][1] = (k-m-1) % mod,a.h[1][2] = (k-m-1) % mod;
    a.h[2][1] = (2*m-k+1) % mod,a.h[2][2] = (2*m-k) % mod;
    matrix d = mpow(a,n-1);
    f[1] = (k-m-1) % mod,g[1] = (2*m-k+1) % mod;
    f[2] = (f[1] * d.h[1][1]) % mod + (g[1] * d.h[1][2]) % mod,f[2] %= mod;
    g[2] = (f[1] * d.h[2][1]) % mod + (g[1] * d.h[2][2]) % mod,g[2] %= mod;
    printf("%lld\n",(f[2] + g[2]) % mod);
    return 0;
    }
    a.h[1][1] = (k-2) % mod,a.h[1][2] = (k-1) % mod;
    a.h[2][1] = (m-k+1) % mod,a.h[2][2] = (m-k+1) % mod;
    matrix d = mpow(a,n-1);
    f[1] = (k-1) % mod,g[1] = (m-k+1) % mod;
    f[2] = (f[1] * d.h[1][1]) % mod + (g[1] * d.h[1][2]) % mod,f[2] %= mod;
    g[2] = (f[1] * d.h[2][1]) % mod + (g[1] * d.h[2][2]) % mod,g[2] %= mod;
    printf("%lld\n",(f[2] + g[2]) % mod);
    return 0;
}

 

T3.station

这题考试的时候我还是只能想到O(nq)模拟,就是维护一下前缀和然后硬算。

然后莫名其妙的爆零了orz……

后来发现,其实对于每个村庄的距离,他相对于上一个村庄的距离就是加上左边的前缀和,减去右边的前缀和,所以其实它是有一定的单调性的。所以其实它是可以使用树状数组维护的……这倒是学了一招,可以直接维护现在的人数总和,然后其实我们只要在树状数组上二分一个人数总和的一半即可,那个位置一定是最小值。

我们来看一下代码吧。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')
#define de putchar('#')
#define pr pair<int,int>
#define mp make_pair
#define fi first
#define sc second
#define lowbit(x) x & (-x)
using namespace std;
typedef long long ll;
const int M = 300005;
const ll INF = 1000000000009;
const ll mod = 998244353;

ll read()
{
    ll ans = 0,op = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') op = -1;
        ch = getchar();
    }
    while(ch >='0' && ch <= '9')
    {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
    }
    return ans * op;
}

ll naive[M],n,q,a[M],p,b,ans,s,minn,mpos,w = 1;

void add(ll x,ll y)
{
    while(x < M) a[x] += y,x += lowbit(x);
    s += y;
}

int query(ll x)
{
    int t = 0;
    ll cur = 0;
    for(int i = (1 << 17);i;i >>= 1) if(cur + a[t+i] <= x) cur += a[t += i];
    return t + 1;
}

int main()
{
        freopen("station.in","r",stdin);
    freopen("station.out","w",stdout);
    n = read(),p = read();
    rep(i,1,n) b = read(),add(i,b);
    while(p--)
    {
        q = read(),b = read(),add(q,b);
        w *= 19260817ll,w %= mod;
        ans += w * query((s-1) >> 1),ans %= mod;
    }
    printf("%lld\n",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/captain1/p/9741418.html

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值