首页 > 其他分享 >CF1411F The Thorny Path

CF1411F The Thorny Path

时间:2024-02-20 15:03:14浏览次数:23  
标签:cnt CF1411F int ans1 else Thorny cnt2 cnt1 Path

转化一下问题,即为给定 \(n, a_{1, \cdots}\) 满足 \(\sum\limits a_i = n\)。
接下来可以花费 \(1\) 代价把 \(x = y + z\) 的 \(x\) 拆为 \(y\) 和 \(z\) 或者把 \(y\) 和 \(z\) 合并成 \(x\)。
求最后的 \(a'\) 的 \(\max\{\prod a'_i\}\) 和达成的最小代价。

首先对于第一问,就相当于是比较 \(x^y\) 和 \(y^x\) 的大小。
考虑取对数变为 \(y\ln x, x\ln y\),同除 \(xy\) 就是 \(\frac{\ln x}{x}, \frac{\ln y}{y}\)。
然后考虑把 \(y = \frac{\ln x}{x}\) 函数图像画出来,发现对于 \(x\in \mathbb{N}_+\),\(x = 3\) 时 \(y\) 最大,次大是 \(x = 2 / 4\)。
于是就可以知道,若 \(n\bmod 3 = 0\),答案为 \(3^{\frac{n}{3}}\);若 \(n\bmod 3 = 1\),答案为 \(3^{\frac{n - 2}{3}}\times 2\);若 \(n\bmod 3 = 1\),答案为 \(3^{\frac{n - 4}{3}}\times 4\)。

然后考虑构造。

对于 \(n\bmod 3 = 0\) 的情况,不难发现就是直接贪心能拆 \(3\) 即拆 \(3\)。
对于剩下的 \(1\) 和 \(2\) 先合 \(1\) 和 \(2\) 再对于剩下的单独合。
正确性可以考虑证明其他的操作方式会比当前的操作方式劣。

然后是 \(n\bmod 3 = 2\)。
这个时候就需要多出来 \(1\) 个 \(2\) 消掉。
考虑到如果把 \(3\) 拆成 \(1, 2\) 其实还是不优(还剩了 \(2\) 显然不优,剩的全是 \(1\) 如果拿 \(2\) 去合并会劣 \(2\),拿 \(1\) 去合并也会劣 \(2\))。
对于那个 \(2\) 一定是用 \(2\) 更优其次才是 \(1, 1\) 合并(考虑只剩单独的 \(1, 2\) 的时候,\(1\) 的操作次数会带个 \(\frac{2}{3}\) 的系数,更优)。

最后是 \(n\bmod 3 = 1\)。
此时剩下的可以是 \(2\) 个 \(2\) 或者 \(1\) 个 \(4\)。
考虑到是 \(1\) 个 \(4\) 一定是要么直接消到 \(4\) 或者是 \(1, 3\) 合出来。
对于剩下的方案因为都 \(\le 2\) 所以肯定是合并成 \(2\) 个 \(2\) 更优。
还是相同的,能消 \(2\) 就消 \(2\)。

时间复杂度 \(O(n + \log P)\)。

#include<bits/stdc++.h>
using i64 = long long;
const i64 mod = 1e9 + 7;
inline i64 qpow(i64 a, i64 b) {
    i64 v = 1;
    while (b) b & 1 && ((v *= a) %= mod), b >>= 1, (a *= a) %= mod;
    return v;
}
const int maxn = 1e6 + 10;
const int inf = 1e9;
int p[maxn], siz[maxn]; bool vis[maxn];
inline void solve() {
    int n; scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", &p[i]);
    int m = 0;
    for (int i = 1; i <= n; i++) vis[i] = 0;
    for (int i = 1; i <= n; i++) {
        if (vis[i]) continue;
        siz[++m] = 0;
        for (int j = i; ! vis[j]; j = p[j]) vis[j] = 1, siz[m]++;
    }
    if (n % 3 == 0) {
        printf("%lld ", qpow(3, n / 3));
        int cnt[3] = {0, 0, 0}, ans = 0;
        for (int i = 1; i <= m; i++) {
            if (siz[i] % 3 == 0) ans += siz[i] / 3 - 1;
            else ans += siz[i] / 3;
            cnt[siz[i] % 3]++;
        }
        if (cnt[1] >= cnt[2]) ans += cnt[2] + (cnt[1] - cnt[2]) / 3 * 2;
        else ans += cnt[2];
        printf("%d\n", ans);
    } else if (n % 3 == 1) {
        printf("%lld ", qpow(3, (n - 4) / 3) * 4 % mod);
        int cnt1[3] = {0, 0, 0}, ans1 = 0;
        bool f = 0;
        for (int i = 1; i <= m; i++) {
            if (siz[i] % 3 == 0) ans1 += siz[i] / 3 - 1;
            else if (siz[i] % 3 == 1 && siz[i] > 1 && ! f) ans1 += (siz[i] - 4) / 3, f = 1;
            else ans1 += siz[i] / 3, cnt1[siz[i] % 3]++;
        }
        if (f) {
            if (cnt1[1] >= cnt1[2]) ans1 += cnt1[2] + (cnt1[1] - cnt1[2]) / 3 * 2;
            else ans1 += cnt1[2];
        } else ans1 = inf;
        int cnt2[3] = {0, 0, 0}, ans2 = 0;
        for (int i = 1; i <= m; i++) {
            if (siz[i] % 3 == 0) ans2 += siz[i] / 3 - 1;
            else ans2 += siz[i] / 3;
            cnt2[siz[i] % 3]++;
        }
        int tot1 = 0, tot2 = 0;
        if (cnt2[1] + cnt2[2] * 2 != n && cnt2[1]) {
            tot1++, cnt2[1]--;
            if (cnt2[1] >= cnt2[2]) tot1 += cnt2[2] + (cnt2[1] - cnt2[2]) / 3 * 2;
            else tot1 += cnt2[2];
            cnt2[1]++;
        } else tot1 = inf;
        if (cnt2[1] + cnt2[2] * 2 >= 4) {
            if (cnt2[2] >= 2) {cnt2[2] -= 2;}
            else if (cnt2[2] == 1) {cnt2[2] = 0, cnt2[1] -= 2, tot2++;}
            else {cnt2[1] -= 4, tot2 += 2;}
            if (cnt2[1] >= cnt2[2]) tot2 += cnt2[2] + (cnt2[1] - cnt2[2]) / 3 * 2;
            else tot2 += cnt2[2];
        } else tot2 = inf;
        printf("%d\n", std::min(ans1, ans2 + std::min(tot1, tot2)));
    } else {
        printf("%lld ", qpow(3, (n - 2) / 3) * 2 % mod);
        int cnt[3] = {0, 0, 0}, ans = 0;
        for (int i = 1; i <= m; i++) {
            if (siz[i] % 3 == 0) ans += siz[i] / 3 - 1;
            else ans += siz[i] / 3;
            cnt[siz[i] % 3]++;
        }
        cnt[2] ? (cnt[2]--) : (cnt[1] -= 2, ans++);
        if (cnt[1] >= cnt[2]) ans += cnt[2] + (cnt[1] - cnt[2]) / 3 * 2;
        else ans += cnt[2];
        printf("%d\n", ans);
    }
}
int main() {
    int T; scanf("%d", &T);
    while (T--) solve();
    return 0;
}

标签:cnt,CF1411F,int,ans1,else,Thorny,cnt2,cnt1,Path
From: https://www.cnblogs.com/rizynvu/p/18023118

相关文章

  • uniapp编译成微信小程序报错-Component is not found in path "components/canvaspage
     问题:我需要将components/canvaspagebg/index引入进pages/index/index   报错了pages/index/index页面引入: uni-app程序编译成微信小程序后,组件无法显示,控制台报错,错误信息为: 我查看了路径,是对的看网上的解决办法就是 我取消勾选后刷新页面就可以了,此时我在选中......
  • Feign动态定义调用serverName与path
    Feign动态定义调用serverName与path查看原文方案一(DynamicProcessFeign)1.定义FeignClient工厂@ComponentpublicclassDynamicProcessFeign<T>{/***缓存feignClient,提高客户端性能*/privatestaticMap<String,Object>processMap=newHashMap<>......
  • Blazor WebApp配置应用基路径PathBase
    BlazorWebApp配置应用基路径PathBase在一个设备数据管理软件系统中,根据生命周期和应用场景不同,可能会划分几个独立的软件子项目。在部署到的时候,可以采用不同的端口号来访问不同的软件子项目,也可以采用统一的端口号和不同的应用基路径来访问不同的软件子项目。基本实现方案:1,......
  • SHGetSpecialFolderPath(NULL, path, CSIDL_PROGRAM_FILES_COMMONX86, 0)
    CStringstr;TCHARpath[MAX_PATH];BOOLb=SHGetSpecialFolderPath(NULL,path,CSIDL_PROGRAM_FILES_COMMONX86,0);//获取指定的系统路径/*参数1:HWNDhwndOwner窗口所有者的句柄。可以NULL参数2:LPTSTRlpszPath返回路径的缓冲区,该缓冲区的大......
  • LD_LIBRARY_PATH和LIBRARY_PATH的区别
    LD_LIBRARY_PATH和LIBRARY_PATH在Linux系统中都是与动态链接库查找路径相关的环境变量,它们的主要区别在于使用阶段和作用:LIBRARY_PATH:作用于程序编译阶段,告诉编译器(如gcc)在编译时寻找动态链接库(.so文件)的附加搜索路径。当编译一个程序,并且该程序依赖于某些非标准路径下......
  • POJ--3764 The xor-longest Path(Trie)
    记录13:562024-2-10找到俩个点,获得最大的边权异或值。利用异或的性质,一个值被异或俩次相当于没有异或即axorbxorb=a所以先从顶点出发,获得每个点路径上的异或值,然后对这俩个值进行异或就获得了他们之间路径的异或值。获取从顶点到每个点路径上的异或值后,可以利用trie来......
  • 微信小程序 Path2D 不支持 svg 路径的解决办法
    问题开发一个微信小程序项目的时候需要用到Path2D这个对象,但是发现小程序的Path2D对象不支持实例化的时候直接传入'svgpath',导致下面的代码运行的时候报错(浏览器中可运行)#其它代码(省略)...//核心代码letp=newPath2D("M1010h80v80h-80Z");//微信小程序中会......
  • 【JAVA】Java 使用 XPath表达式定位节点读取自定义XML方法
    *加载配置文件节点*@paramattributeValue节点属性值*@paramareaCode节点属性值*/publicstaticMap<String,String>getConfigXml(StringattributeValue,StringareaCode){StringfilePath="config.xml";Map<St......
  • Xpath的基本使用
    XPath(全称:XMLPathLanguage)即XML路径语言,它是一门在XML文档中查找信息的语言,最初被用来搜寻XML文档,同时它也适用于搜索HTML文档,因此,自动化测试中可以使用XPath寻找目标节点操作,在爬虫过程中可以使用XPath来提取相应的数据。Xpath使用路径表达式来选取XML/HTML文档......
  • 系统环境变量,python包导入的路径搜索机制,PYTHONPATH,sys.path
    系统环境变量的定义通过在环境变量里面加入所有软件的安装路径,当我们想运行某一软件时双击其快捷方式,此时,计算机除了在其当前目录下寻找该软件的.exe文件外(windows系统),还会在环境变量中搜索软件的路径,找到,运行。综上,Windows中的环境变量,当要求系统运行一个程序而没有告诉它程序......